Известный специалист по серверной и клиентской оптимизации, соавтор WebRTC, автор книги "High Perfomance Browser Networking" Илья Григорик из Google опубликовал презентацию “HTTP/2 all the things!”, в которой объясняет, как следует настраивать серверную часть под HTTP 2.0, чтобы повысить скорость загрузки страниц и уменьшить latency, по сравнению с HTTP 1.1.
Режим Connection View в браузере показывает загрузку элементов заглавной страницы Yahoo.com в HTTP 1.1
Илья начинает с того, что для современных сайтов бóльшая часть задержек приходится на ожидание загрузки ресурсов, при этом полоса пропускания не является ограничивающим фактором (синим цветом на диаграмме Connection View). По статистике, для загрузки средней веб-страницы браузер делает 78 запросов к 12 различным хостам (общий размер загружаемых файлов 1232 КБ).
Для 1 млн крупнейших сайтов интернета, по версии Alexa, на 5-мегабитном канале, среднее время загрузки страницы составляет 2,413 с, при этом CPU работает лишь 0,735 с, а остальное приходится на ожидание поступления ресурсов из сети (latency).
Проблемы HTTP 1.1 заключаются в большом количестве запросов, ограниченном параллелизме, не работающей на практике конвейерной обработке запросов, наличии конкурентных TCP-потоков, оверхеде служебного трафика.
Ещё одна проблема в том, что веб-мастеры перебарщивают с доменным шардингом. Они добавляют слишком много шардов, чтобы обойти ограничение браузера на 6 одновременных соединений с одним сервером, и из-за этого вредят сами себе. Трафик многократно дублируется, возникают заторы, повторные передачи и т.д.
Проблемы с большим количеством запросов при разработке приложений под HTTP 1.1 тоже решаются неправильным образом: через concat (создание больших монолитных фрагментов кода, дорогая инвалидация кеша, отложенное исполнение JSS/CSS) и inline (дублирование ресурсов на каждой странице, сломанная приоритизация).
Что делать?
Всё очень просто. Новый HTTP 2.0 исправляет многие недостатки HTTP 1.1, уверен Илья Григорик. HTTP 2.0 не требует установления множества соединений и уменьшает latency при сохранении привычной семантики HTTP 1.1.
Во-первых, все потоки смешиваются путём разбиения на фреймы (HEADERS, DATA, проч.), которые пересылаются по единственному TCP-соединению. Для фреймов действует приоритет и контроль потока. А server-push заменяет inline. Ну и, конечно, эффективное сжатие заголовков, вплоть до того, что HEADER «сжимается» до 9 байт (передаются только изменения).
Как конкретно использовать преимущества HTTP 2.0 для оптимизации серверных приложений? Это самая интересная часть презентации Ильи Григорика.
Устраняем доменный шардинг
Шардинг конкретно бьёт по производительности HTTP/2, ломает приоритизацию фреймов, контроль потока и проч.
В случае необходимости можно реализовать шардинг через altName
. Если используется один IP и один сертификат, то HTTP/2 сможет открыть единственное соединение для всех шардов.
Избавляемся от ненужных оптимизаций (concat, CSS-спрайты)
Потоки больше не являются ограничением, так что можно грамотно распределять ресурсы по модулям, задавать стратегию кеширования для каждого из них.
Внедряем server-push вместо inline
Сервер теперь может выдавать несколько ответов на один запрос. Клиент заказывает что-то одно, а сервер ему может дать в придачу и что-то другое. Каждый ресурс кешируется независимо (при этом необязательно кэшировать на каждый запрос, есть smart push). Кстати, с помощью серверного push-уведомления можно и аннулировать запись в клиентском кеше!
Smart push — вообще отличная вещь. Сервер сам анализирует трафик и строит зависимости, какие ресурсы запрашивает клиент, в зависимости от referrer’а. Например, index.html → {style.css, app.js}. В соответствии с этими закономерностями и создаются правила для дальнейших push-уведомлений новым клиентам.
Илья Григорик подчёркивает, что в случае с HTTP/2 серверы обязательно должны быть правильно сконфигурированы. Это не было так критично во времена HTTP/1.1, но теперь так оно и есть. Например, в HTTP/1.1 браузер сам высылал сначала важные запросы (index.html, style.css), придерживая второстепенные (hero.jpg, other.jpg, more.jpg и проч.), теперь же нет. Так что если не сконфигурировать сервер на обработку важных запросов в первую очередь, то пострадает производительность.
Далее, HTTP/2 позволяет тонко контролировать поток. Например, можно сначала отправить первые несколько килобайт изображения (чтобы браузер декодировал заголовок и определил размеры картинки), потом важные скрипты, а затем уже остальную часть изображения.
Тестирование показало, что при использовании SPDY задержка (latency) и скорость загрузки страницы уменьшаются на 30-40%.
Например, Twitter протестировал задержку доступа к API в декабре 2013-го. Результаты в миллисекундах показаны на графике для 50-й, 75-й, 95-й и 99-й перцентили (по медиане). Интересно, что SPDY приносит больше пользы, когда клиент подключен по худшему каналу связи (low latency locale).
Компания Google публиковала свою статистику по увеличению скорости загрузки страниц ещё год назад.
Google News | Google Sites | Google Drive | Google Maps | |
По медиане | -43% | -27% | -23% | -24% |
5-я перцентиль (быстрые соединения) |
-32% | -30% | -15% | -20% |
95-я перцентиль (медленные соединения) |
-44% | -33% | -36% | -28% |
Встроенная поддержка HTTP/2 появится в ближайшей стабильной версии Chrome 39 и в ближайшем стабильной версии Firefox 34, так что всего через несколько месяцев большинство браузеров в интернете будут поддерживать HTTP/2 и смогут пользоваться преимуществами нового протокола (поскольку SPDY стал частью HTTP/2, то теперь его отдельная инкарнация выводится из обращения).
На Github ведётся список известных реализация HTTP/2 на C#, NodeJS, C++, Perl и т.д. Туда входит и библиотека nghttp2 на C. В общем, Илья Григорик призывает всех оптимизировать свои серверы под HTTP/2 и проверить корректную работу TLS.
Автор: alizar