Your SlideShare is downloading. ×
Eternal static (RIT 2011)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Eternal static (RIT 2011)

502
views

Published on

«Вечная статика» оптимизация отдачи контента

«Вечная статика» оптимизация отдачи контента

Published in: Technology

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
502
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
5
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. «Вечная статика»оптимизация отдачи контента
    Сергей Скворцов
    2011-04-26
  • 2.
  • 3. I. Теория
    3
  • 4. Стороны и связь
    Браузер
    отображение/рендеринг страниц/данных
    Протокол
    передача данных: запрос-ответ или stream
    Сервер
    приём запросов, формирование и передача ответов
  • 5. Скорость показа контента
    Скорость отображения в браузере
    Скорость передачи по сети
    Скорость ответа от сервера
  • 6. 1)Скорость отображения в браузере
    Рендеринг / вёрстка
    Встраивание ресурсов/данных
    Data URI, CSS sprites
    увеличивает размер ответа
    AJAX, WebSockets
    Отложенная загрузка;Prefetching
    JavaScript: async/defer; post-load
  • 7. 1.1) Рендеринг/вёрстка
    Корректный порядок указания ресурсов (JS/CSS)
    Yahoo «Best Practices for Speeding Up Your Web Site»
    Самоограничения: CSSexpressions
    Прогрессивная вёрстка
    см. StoyanStefanov (Yahoo)
    Верстка независимыми блоками
    см. Виталий Харисов (Яндекс)
    Шаблоны на client-side (XSLT)
  • 8. 2)Скорость передачи по сети
    Каналы…
    … связность, распределение по странам, ДЦ
    DNS-resolving
    Уменьшение числа lookup’ов (число хостов, TTL)
    Geo-balancing, IP anycast
    Постоянные соединения
    HTTP 1.0 keep-alive == HTTP 1.1 persistent
  • 9. 2)Скорость передачи по сети
    Раздача с нескольких хостов
    CDN; DNS/geo-balancing, TCP anycast
    Параллелизация загрузки: default лимит у браузеров – не более 6 запросов на хост
    JS-хостинги (для jQuery, YUI, …)
    13% страниц используют Google Libraries API
    Хорошо кэшируютсямежду сайтами
    Privacy: источник Referer’ов для поисковиков
  • 10. 2)Скорость передачи по сети
    HTTP pipelining - не популярен
    Дружим с proxy-servers, и ненавидим их
    Кэширование!
    Их 10% запросов (оценка по Openstat.Trends)
    «Над»-протоколы (HTTPS, SPDY)
    HTTPS – безопасность, но overhead
    SPDY – только Google, нет поддержки в nginx :)
  • 11. 3)Скорость ответа от сервера
    Скорость генерации ответа
    Уменьшение размера ответа
    Уменьшение размера запроса
    Уменьшение числа запросов
  • 12. 3.1) Скорость генерации ответа
    Хорошие frontend’ы
    Быстрые серверы приложений (backend’ы)
    Прогрессивная отдача контента
    flush()
    Кэширование:
    данных (memcached)
    ответа (mod_cache*)
  • 13. 3.2) Уменьшение размера ответа
    Сжатие ответа
    ngx_http_gzip, ngx_http_gzip_static
    mod_gzip, mod_deflate
    Отложенная «подгрузка» JS, контента
    Post-loading
  • 14. 3.2) Уменьшение размера ответа
    Оптимизация содержимого (minification)
    Оптимизация JS/CSS
    Closurecompiler, YUI Compressor
    Оптимизация графики
    Оптимизация HTML
    Пробелы, комментарии, default атрибуты, …
    htmlcompressor,или при компиляции шаблонов 
  • 15. 3.3) Уменьшение размера запроса
    Отдача статики в другом домене
    Чтобы не слать лишние заголовки: Cookie
    Уменьшаем размер Cookie
    FYI: максимальный суммарный размер на домен:
    Firefox, Chrome - no limit
    Opera, IE6 - 4096байт
    IE8 - 10234байт
  • 16. 3.4) Уменьшение числа запросов
    Кэширование контента на стороне браузера
    Объединение стилей и скриптов (JS, CSS)
    Объединение и внедрение картинок(CSS sprites, Data URI, MHTML)
    ценой большего размера ответа
    Избегать редиректов
  • 17. Итого
    Всё вышеописанное можно использовать как checklist, варианты ответов:
    Уже так делаем
    Не делаем, потому что (программисты|админы) сказали что…
    Не знали / совсем забыли – надо подумать
  • 18. II. Приём
    18
  • 19. Как работает кэширование в HTTP
    При первом запросе к ресурсу браузер:
    Запоминает заголовки ответаLast-Modified и/ли ETag
    Определяет сколько времени можно не обращаться к серверу, а использовать локальный кэш - на основе данных из заголовков:
    Expires
    Cache-Control
    http://www.w3.org/Protocols/HTTP/1.1/rfc2616bis/
  • 20. Как работает кэширование в HTTP
    При втором запросе к серверу:
    Если ресурс в локальном кэше – браузер делает валидацию – шлёт условный запрос:
    If-Unmodified-Sinceи/ли If-None-Match
    Если ресурс не менялся (304 Not modified):ждём опять expiration
  • 21. Нюансы де-факто
    По факту ETagиспользуетсядля статики так:
    nginx: не вычисляет вообще
    Apache:inode-size-timestamp
    IIS:Filetimestamp:ChangeNumber
    Это не работает на кластере машин
    inodeи ChangeNumberбудут разные
  • 22. Проблемы этого дня
    Заголовки ExpiresиCache-Control: max-age тупо не выставляют
    56% запросов вообще не указывают expiration
    24% запросов может кэшироваться http://www.stevesouders.com/blog/2011/04/18/http-archive-max-ag/
    Нопри этом есть статика – которая меняется редко:
    CSS, JavaScript, картинки, Flash, иконки (!)
  • 23. Проблемы этого дня
    Поскольку нет expiration – каждый раз шлётся запрос (в надежде на 304 Not modified)
    Но такой запрос это:
    Минимум 2 IP пакета
    Время на ожидание ответа
    Особенно печально ждать когда блокируемся на рендеринге
  • 24. Решение: выставлять expiration
    Выставлять expiration для динамики несложно (семантику знает backend)
    Но любой константный expiration для статики приводит к проблемам при обновлении сайта (новый дизайн, шаблоны, …)
    Единый глобальный Expire - выставить нельзя
    Выход: версионированиена уровне URI
  • 25. Версионирование
    Наивный подход – добавлять «?» + timestamp: /favicon.ico?ver=3
    Многие прокси серверы считают URL с «?» некэшируемым в принципе
    Не учитываются зависимости внутри ресурса:
    /style.css?ver=3ссылается внутри на /logo.png?ver=5
  • 26. Версионирование: верный подход
    Добавляем версию внутрь пути: /favicon_1303591683.ico
    Версию можно брать из VCS, но не каждый ресурс лежит в репозитории, он может создаваться при выкатке
    Очевидный вариант – timestamp
    Для файлов с зависимостями «наружу» – считаем версию с учётом зависимостей, пример:
    md5( timestamp + @versioned_dependencies_urls)
    Экономим байты – используя Base64 URLSafe
  • 27. Обработка внешних зависимостей
    Делаем общий префикс /s/в URLах статики
    Для всех шаблонов, которые ссылаются на версионированную статику, обновляем ссылки
    Всё! Статика стала вечной, поэтому:
    location /s/ {
    expires max;
    gzip_static on;
    }
  • 28. Применимость
    • Стоит применять для:
    Файлов стилей и скриптов (CSS, JS)
    Картинок, являющихся частью дизайна/шаблона
    Flash-объектов
    • Не надо применять для:
    Скачиваемых файлов (и подлежащих индексации)
    Особо актуально:
    Мобильные сайты
  • 29. Немного статистики:число запросов
  • 30. mime-types:по числу запросов
  • 31. mime-types:медиана размера ответа
  • 32. HTTP Archive:медиана размера ответа
    http://httparchive.org/interesting.php#responsesizes
  • 33. 33
    III. Практика
  • 34. Htdocs layout
    На файловой системе:
    htdocs/
    frontend/
    eternal/
    backend/
    • frontend - статика, отдаётся nginx
    • 35. eternal– «вечная» статика, отдаётся nginx
    • 36. backend - шаблоны, используются в upstream
  • VCS layout
    В репозитории:
    trunk/
    htdocs-frontend/
    a/
    css/
    img/
    js/
    htdocs-backend/
  • 37. Сборка пакетов: шаги
    Checkout
    Processing
    Стадия «generate»
    Стадия «preprocess»
    Стадия «optimize»
    Стадия «produce»
    Генерация «вечной статики» (кладём в /s/)
    Packing distfiles
  • 38. Сборка пакетов – Processing
    Стадия «generate»
    Генерация новых файлов, на основе checkout’а
    img2css– набор иконок в один CSS файл
    Стадия «preprocess»
    Изменение содержимого файла, и/ли метаданных о нём
    inline-includes– объединение файлов
    CSS: раскрытие @import
    JavaScript: раскрытие _include_js()
  • 39. Сборка пакетов – Processing
    Стадия «optimize»
    Оптимизация формата файла, с сохранением инварианта его семантики
    yuicompressor– JS/CSS minification
    Стадия «produce»
    Генерация других файлов на основе итоговых
    gzip_static– создание сжатой версии статики
  • 40. Сборка пакетов – «вечная» статика
    Конфигурация:
    <handler
    name="eternal-static"
    process_path="/a/"
    target_path="/s/"
    match_ext="gif icojpg pngswfjscss"
    expand_ext="jscss"
    />
  • 41. Сборка пакетов – «вечная» статика
    Сканируем директорию process_pathна предмет статических файлов с нужными расширениями
    Обрабатываем раскрываемые файлы (*.js *.css) на предмет ссылок на другие найденные ранее статические файлы
    Строим граф зависимостей
  • 42. Сборка пакетов – «вечная» статика
    В директории target_pathсоздаём соотв. версии статических файлов (и их gzipped-версий, если у файлов был handlergzip_static)
    Итоговый файл будет называтьсяfilename_revision.ext, где revision – ревизия файла
    /a/file.txt /s/file_REVISION.txt
  • 43. Сборка пакетов – «вечная» статика
    Для статического файла, который не имеет зависимостей (в т.ч. тех, которые не раскрываются вообще, типа картинок), ревизия равна mtime
    VCS ревизия может быть недоступна, если файл генерировался.
    При генерации файлов mtimeфинального файла всегда равен максимальному mtimeего исходных файлов
  • 44. Сборка пакетов – «вечная» статика
    Для статического файла, который имеет зависимости, ревизия вычисляется как md5( join('0', mtime, sort@eternal_static_deps) ) - т.е. создаётся семантически уникальная ревизия файла.
    Жёсткое создание ревизии (md5 от тела файла) не используется, чтобы при изменениях контента, которые семантически инвариантны (например, применён новый алгоритм оптимизации/obfuscation файлов) не создавалась новая ревизия.
  • 45. Сборка пакетов – «вечная» статика
    Создаём файл /s/.mapping, который содержит строки с парами "статический файл", "вечно-статический файл":
    /a/js/base.js /s/js/base_iv6uTQ.js
    /s/css/main.css /s/css/main_msy5mT8H-Ak6hBAsce-30w.css
  • 46. Пример: www.openstat.ru
    <!DOCTYPE HTML><html lang="ru"><head>
    <title>Интернет-статистика и веб-аналитика | Openstat: Независимая аналитика</title>
    <link rel="stylesheet" type="text/css" href="/s/css/main_msy5mT8H-Ak6hBAsce-30w.css" />
    <script type="text/javascript" src="/s/js/base_iv6uTQ.js"></script>
  • 47. Установка пакетов
    Файлы ставятся в share/htdocs/frontend
    На этапе POST-INSTALL запускаем:
    rsync -rlptgoD--checksum--delete-after
    share/htdocs/frontend
    htdocs/frontend
    Это делается для того, чтобы при удалении пакета в htdocs/frontendчто-то оставалось
  • 48. Установка пакетов
    Также копируем вечную статику:
    rsync -rlptgoD--checksum
    htdocs/frontend/s/
    htdocs/eternal
    В htdocs/eternalфайлы никогда не удаляются!
  • 49. Установка пакетов
    Раскрываем(и атомарно замещаем) файлы шаблонов по списку из /s/.mapping:htdocs/backend
    Поскольку директория /a/также ставится, то задержка в раскрытии файлов, равно как их нераскрытиене влияет фатально на работу сайта - просто запросы пойдут к "менее вечной" статике.
  • 50. Конфигурация frontend’а
    Пример для обычного веб-сервера:
    location ^~ /s/ {
    alias htdocs/eternal;
    gzip_static on;
    expires max;
    }
  • 51. Соглашения
    Соглашения для раскрываемых файлов:
    Полное указание пути на ссылаемые файлы
    В JS не использовать составление URLиз частей , прописывать в коде полностью(как hash)
  • 52. favicon
    • IE(и иные браузеры) всегда запрашивают /favicon.ico, если нет<link rel=”icon” …/>
    Выдавать 404 – не выход, поскольку запросы всё равно будут идти
    Правильно так:
    location = /favicon.ico {
    root /path/to/htdocs;
    expires 30d;
    }
  • 53. IV. Tips & tricks
    52
  • 54. Битва за байты: заголовки
    Заголовок Server:
    Вообще-то его надо оставлять – это полезная статистика
    https://www.openstat.ru/counter/trends/
    Но надо убирать из него длинных список скомпилированных модулей:
    Server: Apache/1.3.27 (Unix) mru_xml/0.471 gorgona/2.1 mod_jk/1.2.4 mod_ruby/1.0.7 Ruby/1.6.8 mod_mrim/0.17
    Также убирать прочие «гордые» заголовки:
    X-Powered-By: PHP/5.2.6-1+lenny9
  • 55. Битва за байты: HTML5 vs. XHTML
  • 56. Используем TLS/SSL
    TLS/SSL – уже не дорого в плане вычислений (CPU)
    Отдельные аппаратные акселераторы уже не нужны
    CPU Intel Core i5+ поддерживают AES instruction set
    Privacy & confidentiality – всегда популярно среди параноиков
    https://gmail.com, https://encrypted.google.com
    Цена сертификата Thawte - всего $45
  • 57. Минусы TLS/SSL
    Дополнительные 4+ IP пакета на handshake (размер public key имеет значение!)
    Больший размер ответов
    record header, padding (если block cipher)
    При тщательно подобранном размере ответа ресурса (чтобы, скажем, влез в 1 IP пакет),применение SSL может повлечь +1 IP пакет
  • 58. Минусы TLS/SSL
    Блокирование на OCSP (проверка сертификата сервера) = +N*100ms
    FF3+; IE* on Vista / Win7, …
    Решение - OCSP stapling
    Не работает с chained certs
    +~1KB данных (OCSP ответ)
    Есть в Apache, нет в nginx
  • 59. Минусы TLS/SSL
    SSL + IE6/7+data:uriв HTML =«небезопасный ресурс»
    Доля IE6 + IE7 в Рунете - 9%
    SSL + отдача статики параллельно с нескольких хостов= дополнительные затраты на сертификаты
    либо несколько сертификатов для разных хостов (www.foobar.ru, img.foobar.ru)
    либо условно дорогой wildcard(*.foobar.ru)
  • 60. Вопросы?(по теме доклада)
    http://protey.ru/blog/2011/04/rit-2011.html
    Сергей Скворцов
    skv@protey.ru
    59

×