Что такое HTTP/2 и как он помогает ускорять сайты
HTTP (HyperText Transfer Protocol) — протокол прикладного уровня (L7 по модели OSI), определяющий, как контент передаётся по сети. HTTP/2 — это его последняя версия на момент выхода публикации.
История создания HTTP/2
Описание первой версии, 0.9, было опубликовано ещё в 1991 году. В 1996-м появился HTTP1.0. А предшественник HTTP2 (HTTP 1.1) — вышел в 1999-м. После этого долго не было никаких обновлений.
Альтернативу HTTP1.1 разработали в 2009 году. Это был протокол SPDY. Тогда у разработчиков было понимание, что существующий вариант уже недостаточно быстрый. Целью инженеров было модифицировать способы приёма и отправки сообщений и ускорить работу интернета. Именно SPDY лёг в основу HTTP2.
SPDY действительно ускорял веб-приложения, поэтому набирал популярность. В итоге разработчики решили, что в сети не должно быть двух конкурирующих стандартов, и объединили их. За создание объединённого стандарта взялась рабочая группа HyperText Transfer Protocol из Инженерного совета Интернета и выпустила его в 2015 году.
Основной целью было ускорение отдачи данных. Ещё разработчики хотели избавиться от «узких мест», сделать стандарт более производительным и безопасным.
История создания HTTP/1.1
Как мы уже сказали, он вышел в 1999 году. Следующий стандарт появился через 16 лет. За это время в интернете многое изменилось, появились новые элементы: скрипты JаvaScript, анимация, стили CSS и много чего ещё.
Чтобы веб-ресурсы загружались за достаточно короткое время, запросы на разные элементы надо было обрабатывать одновременно. Приходилось создавать сразу несколько TCP-соединений для отправки различных типов файлов.
Это создавало колоссальную нагрузку на сеть.
При этом количество установленных TCP-соединений было ограничено, и их часто было недостаточно. Чтобы обойти ограничения, веб-разработчики использовали множество трюков, таких как доменный шардинг (использование поддоменов для загрузки веб-ресурсов), объединение нескольких картинок в одну и так далее. Это создавало дополнительные сложности.
Кроме того, так как HTTP1.1 существовал уже много лет, в какой-то момент он перестал отвечать требованиям безопасности. Злоумышленники нашли в нём лазейки, позволяющие воровать данные пользователей.
В общем, требовалась оптимизация. И обновлённый стандарт решил эти проблемы, помог значительно ускорить доставку в интернете.
Возможности HTTP/2: как он ускоряет сайты и улучшает передачу данных
Чтобы устранить существующие проблемы, разработчики внесли ряд важных изменений. Не будем рассматривать все отличия, поговорим о тех, которые непосредственно влияют на скорость.
Бинарная природа
Предыдущие версии передавали информацию в текстовом формате. Это было удобно для пользователей. Но с технической точки зрения текстовые сообщения обрабатываются медленнее, чем бинарные.
Во втором стандарте сообщения состоят из фреймов — бинарных частей данных. Их совокупность называется потоком (стримом, stream). Каждый фрейм содержит уникальный идентификатор — сведенья, к какому стриму он относится.
Существует несколько типов фреймов. Например, для отправки метаданных (размера, типа документов, адресов отправителя и получателя и так далее) используется фрейм HEADERS, для основного содержимого — фрейм DATA.
Есть фрейм RST_STREAM — он используется для прерывания потока. Клиент передаёт его, чтобы сообщить, что стрим больше не нужен. Доставка останавливается, но соединение остаётся открытым. Раньше единственным способом прекратить отправку был разрыв TCP-соединения, потом его приходилось открывать заново.
Такой принцип работы повышает качество соединения:
- Снижается вероятность ошибки.
- Уменьшаются накладные расходы при парсинге данных.
- Снижается нагрузка на сеть, ресурсы используются более эффективно.
- Бинарные команды компактнее текстовых, что снижает время на их обработку и выполнение.
- Следовательно, уменьшаются задержки.
- Более простая обработка означает большую устойчивость к сбоям.
- Снижается риск хакерских атак, особенно таких, как HTTP Response Splitting. Раньше возможности для таких атак открывала текстовое содержание заголовков.
Кроме того, бинарная природа открывает целый ряд возможностей для ускорения, о которых сейчас поговорим.
Мультиплексирование
Одно из главных отличий. Благодаря этой особенности удалось ускорить доставку.
У предшественника для отправки разных типов файлов создавалось несколько параллельных TCP-соединений. В новой версии всё может отправляться с помощью одного.
Бинарный характер даёт возможность параллельно загружать различный контент без задержек, не блокируя ни один из ответов.
Потребность устанавливать только одно соединение сильно сокращает время на доставку. Дело в том, что для установки каждого TCP-соединения требуется «тройное рукопожатие»:
- Браузер запрашивает установку соединения — отправляет SYN, порядковый номер переданного байта.
- Получатель в ответ посылает SYN, подтверждает получение с помощью ACK и отправляет номер байта, который должен быть получен следующим.
- Браузер тоже подтверждает получение, посылает номер следующего ожидаемого байта.
Только после этих трёх шагов связь считается установленной. Если используется https, добавляются дополнительные шаги.
На всё это уходит время. Когда связь необходимо установить только один раз, время на лишние «рукопожатия» не тратится, а следовательно, увеличивается скорость.
Кроме того, отпадает необходимость в доменном шардинге.
Чтобы обойти ограничение на количество TCP-соединений, разработчики выносили часть содержимого на поддомены. Данные с поддоменов загружались параллельно, это помогало ускорить процесс.
Теперь это делать не нужно, так как различный контент посылается в одном TCP-соединении, без ограничений.
Сжатие заголовков
Чтобы получить наиболее точный ответ, заголовок должен содержать как можно больше уточняющих метаданных. В протоколе без сохранения состояния (каким является предмет нашей статьи) сервер не может хранить сведенья из предыдущих запросов. Клиенту приходится каждый раз посылать большое количество повторяющихся сведений.
Объём таких заголовков — около 500–800 байт служебной информации, а иногда больше килобайта, если используются cookie.
Это делает сообщение в целом более объёмным. Чем больше размер, тем дольше оно будет отправляться, тем больше будет задержка.
Ситуацию исправило сжатие с помощью формата HPACK — кодирует, сжимает заголовки с помощью алгоритма Хаффмана. Вместе с этим клиент и веб-сервер поддерживают общую, постоянно обновляемую таблицу заголовков. Это позволяет не передавать повторяющиеся, а восстанавливать их с помощью таблицы.
Сведений отдаётся меньше, и они доходят быстрее.
Функция Server Push
Эта функция позволяет передавать сведенья до того, как клиент их запросил. Например, браузер загружает страницу и просит HTML. Но вместе с HTML для отрисовки страницы потребуются CSS. Источник не ждёт второго запроса на CSS, отправляет их сразу вместе с запрошенными.
«Угаданные» файлы отправляются с помощью фрейма PUSH_PROMISE. Так клиент сможет понять, что это информация, которую он не запрашивал, и определить, нужна ли она. Если сведенья окажутся не нужны (например, потому что они есть в кеше), браузер может послать в ответ фрейм RST_STREAM (говорили о нём выше) и остановить отправку лишнего.
Это помогает избежать дублирования.
Таким образом, функция сокращает количество запросов, уменьшает нагрузку и ускоряет работу веб-приложений.
Приоритизация отдачи контента
Сообщения по умолчанию отправляются асинхронно, в произвольной последовательности. Однако эту последовательность можно задать. Можно определить, что надо отдавать в первую очередь, а что можно отправить позже.
Протокол позволяет определить вес каждого потока — его значимость в плане приоритетности отдачи. При этом даётся возможность установить зависимость одного стрима от другого.
Вес определяется в виде целого числа от одного до 256. Чем больше число, тем более приоритетным будет поток.
Зависимость одного стрима от другого указывается с помощью специального идентификатора, который отсылает к другому, «родительскому» потоку.
Например, если поток X зависит от Y, это значит, что Y — родительский стрим, и он должен быть полностью обработан в первую очередь, а уже после будет обрабатываться X.
Если стримы не зависят друг от друга, но имеют разный вес, на их обработку выделяется разное количество ресурсов пропорционально их весу.
Допустим, X и Y не зависят друг от друга, но при этом X весит 10, а Y — 15. Давайте посчитаем, сколько процентов будет выделено каждому:
- X + Y = 10 + 15 = 25
- Мощности, выделяемые на X = 10 / 25 = 40%
- Мощности, выделяемые на Y = 15 / 25 = 60%
Получается, на обработку X будет выделено 40%, а на обработку Y — 60%.
Давайте рассмотрим, как это работает, на более развёрнутом примере.
Что означает схема:
- D должен быть обработан в первую очередь.
- E и C должны быть обработаны после D. На каждый должно быть выделено по 50% ресурсов.
- A и B будут обработаны после C. На A будет выделено 75% мощностей, на B — 25%.
Какие возможности даёт приоритизация:
- Вы можете определить, что будет загружаться в первую очередь.
- Первый приоритет можно отдать самым важным для пользователей элементам.
- Юзеры получат все необходимые для взаимодействия элементы раньше, чем загрузка завершится полностью.
- Это создаст впечатление более быстрой загрузки и улучшит клиентский опыт.
Как HTTP/2 ускоряет сайты на практике
С момента выхода HTTP2 прошло много времени, он успел много раз пройти проверку и сравнение с HTTP/1.1. Разные тесты показывают отличающиеся результаты, но большинство действительно подтверждают — новая версия обходит предшественника в производительности.
Например, тест CCS-Tricks показал — веб-ресурс с HTTP2 загружается почти в два раза быстрее.
Для тестирования компания смоделировала реальный одностраничный сайт на WordPress. Для измерения времени загрузки они использовали инструмент GTMetrix.
В результате, используя HTTP1.1, страницу удалось загрузить за 1,9 с. Со вторым стандартом при тех же условиях время загрузки составило одну секунду.
При этом, используя HTTP2, удалось уменьшить количество запросов.
Испытания компании SolarWinds демонстрируют не столь впечатляющие результаты. Их тестирование HTTP2 vs HTTP/1.1 показывает, что производительность первого выше всего на 13%.
Так же, как и в предыдущем исследовании, компания замеряла скорость веб-ресурса на WordPress, используя Pingdom.
Тесты проводили 4 раза через каждые 30 минут. Из получившихся результатов они вывели средний показатель. И вот что получилось.
Сайт с предшественником загружался 534 мс. Тот же веб-ресурс на новом стандарте загрузился за 464 мс.
Так или иначе, вторая версия основного протокола передачи данных в интернете сейчас является наиболее оптимизированной.
Подведём итоги
- HTTP/2 — вторая крупная версия HTTP — сетевого протокола прикладного уровня, который определяет, как контент передаётся по интернету.
- Был выпущен в 2015 году. Основной целью было ускорить передачу.
- Главная особенность, за счёт которой удалось ускорить доставку, — мультиплексирование потоков. Оно позволяет создавать одно соединение для любого типа файлов и передавать их параллельно.
- Помимо этого, информация доставляется быстрее за счёт сжатия заголовков, приоритизации и функции Server Push. Бинарный характер повышает производительность.
- Проведённые тесты показывают, что использование HTTP/2 даёт существенное преимущество в скорости загрузки.
EdgeCDN поддерживает HTTP/2. При этом сеть может доставлять контент по нему, даже если ваши серверы его не поддерживают.