Краткое содержание чтения "Учебник по основам HTTP/2"

HTTP TCP/IP
Краткое содержание чтения "Учебник по основам HTTP/2"

В последнее время было много сообщений и дискуссий, связанных с HTTP2, и я чувствую, что формируется новый виток тенденций, поэтому недавно я нашел эту книгу, связанную с HTTP2, в качестве резерва знаний, которую я просто записал в качестве примечания для будущих запросов. ~

Если вы хотите получить ресурсы этой книги в формате PDF, вы можете использовать QR-код в конце статьи и добавить группу WeChat, чтобы найти основную группу~

Сама книга хороша, но недостатком является то, что перевод немного хромает, Кроме того, поскольку это книга, опубликованная в 2017 году, часть контента не очень своевременна, например, часть о Chrome, поэтому я добавил некоторые контент основан на официальной документации Chrome 😅

1. История эволюции HTTP

1.1 HTTP/0.9, HTTP/1.0, HTTP/1.1

  1. HTTP/0.9:Это довольно простой протокол. У него есть только один метод (GET), нет заголовков, и цель его разработки — не что иное, как выборка HTML (то есть никаких изображений, только текст).
  2. HTTP/1.0:Есть много других функций, таких как заголовки, коды ошибок, перенаправления, условные запросы и т. д., но все еще есть много недостатков, особенно невозможность разрешить нескольким запросам совместное использование соединения, отсутствие обязательного заголовка Host и Выбор кэширования довольно прост.Эти три пункта влияют на то, насколько расширяема сеть.
  3. HTTP/1.1:Добавлены расширения для заголовков, связанных с кешем,OPTIONSметод,Upgradeстолица,RangeЗапрос и передача закодированного сжатия, конвейера и других функций. Поскольку обязательный клиент предоставляет заголовок Host, поэтомувеб хостингНа одном IP-адресе можно предоставлять несколько веб-сервисов. дополнительно используетсяkeep-aliveПосле этого веб-серверу также не нужно закрывать соединение после каждого ответа. Это важно для повышения производительности и эффективности, поскольку браузеру больше не нужно повторно инициировать TCP-соединение для каждого запроса.

1.2 HTTP/2

Ожидается, что HTTP2 будет иметь следующие характеристики:

  • По сравнению с HTTP/1.1 производительность значительно улучшена;
  • Решить проблему блокировки заголовка строки в HTTP;
  • Механизм параллельной реализации не полагается на установление множественных соединений с сервером, тем самым улучшая использование TCP-соединений, особенно с точки зрения контроля перегрузки;
  • Сохраняет семантику HTTP/1.1 и может использовать существующие ресурсы документации, включая (но не ограничиваясь) методы HTTP, коды состояния, URI и поля заголовков;
  • Явно определите HTTP/2.0 и HTTP/1.xСпособы взаимодействия, особенно при прохождении через посредника (двусторонние);
  • Явно определите новые точки расширения и стратегии, для которых их можно разумно использовать.

2. Быстрый старт HTTP/2

2.1 Приступаем к работе

Многие веб-сайты уже используют HTTP/2 (h2), такие как Facebook, Instagram, Twitter и т. д. Ниже описано, как самостоятельно создать сервер h2. Чтобы запустить сервер h2, нужно выполнить два основных шага:

  1. Получите и установите веб-сервер, поддерживающий h2
  2. Загрузите и установите сертификат TLS, чтобы браузер и сервер могли подключаться через h2.

2.2 Получение сертификата

Сертификаты можно получить тремя способами:

  1. Используйте онлайн-ресурсы
  2. Создать сертификат самостоятельно
  3. Подать заявку на сертификат в цифровом центре сертификации (ЦС)

Первые два метода создадут самоподписанный сертификат, который используется только для тестирования.Поскольку он не выдается ЦС, браузер выдаст предупреждение

Я не вспомню шаги по созданию сервера h2 позже, вы можете скачать его с Baidu

3. Мотивация и метод веб-оптимизации "Черная магия"

3.1 Текущие проблемы с производительностью

3.1.1 Анализ запросов веб-страницы

Что именно происходит за это время с момента, когда пользователь щелкает ссылку в браузере, до отображения страницы на экране? Когда браузер запрашивает веб-страницу, он выполняет итеративный процесс, чтобы получить всю информацию, необходимую для отображения страницы на экране. Чтобы упростить понимание, мы разделим этот процесс на две части: получение ресурсов и парсинг/рендеринг страницы.

Блок-схема запроса ресурсов:

Процесс:

  1. Очередь запрашиваемого URL
  2. Разрешить IP-адрес доменного имени в URL-адресе (A)
  3. Установите TCP-соединение с целевым хостом (B)
  4. Если это запрос HTTPS, инициализируйте и завершите рукопожатие TLS (C)
  5. Отправьте запрос на URL, соответствующий странице.

Блок-схема ответа ресурса:

  1. получить ответ
  2. Если (получено) является HTML-кодом тела, то проанализируйте его и запустите механизм приоритетной выборки (A) для ресурса на странице.
  3. Если ключевой ресурс на странице получен, начинаем рендерить страницу (B)
  4. Получить другие ресурсы и продолжить синтаксический анализ и рендеринг до конца (C)

Для каждого клика на странице необходимо повторять предыдущие процессы, что оказывает давление на пропускную способность сети и ресурсы устройства. веб-производительность оптимизированаосновной, заключается в ускорении или даже полном удалении некоторых из этих шагов.

3.1.2 Ключевые показатели эффективности

Ниже приведены показатели производительности на уровне сети, которые влияют на общую загрузку веб-страницы.

  1. Задерживать:Относится ко времени, которое требуется IP-пакету для перемещения от одной конечной точки сети к другой.
  2. пропускная способность:Пока полоса пропускания не перегружена, соединение между двумя конечными точками сети обрабатывает максимально возможный объем данных одновременно.
  3. DNS-запрос:Прежде чем клиент сможет получить веб-страницу, ему необходимо преобразовать имя хоста в IP-адрес через систему доменных имен (DNS).
  4. Время установления соединения:Для установления соединения между клиентом и сервером требуется трехстороннее рукопожатие. Время рукопожатия обычно связано с задержкой между клиентом и сервером.
  5. Время согласования TLS:Если клиент инициирует HTTPS-соединение, ему также необходимо согласовать безопасность транспортного уровня (TLS), что приводит к дополнительному круговому обходу.
  6. Время до первого байта (TTFB):TTFB относится ко времени, которое требуется клиенту, чтобы найти веб-страницу и получить первый байт ответа главной страницы. Он включает в себя различные времена, упомянутые ранее, плюс время обработки сервером. Для ресурсов на главной странице TTFB измеряет время, прошедшее между тем, когда браузер инициирует запрос и получает свой первый байт.
  7. Время загрузки контента:Эквивалентно времени поступления последнего байта (TTLB) для запрошенного ресурса.
  8. Время начала рендеринга:Когда на экране клиента начинает отображаться контент? Этот показатель измеряет, как долго пользователь видит пустую страницу.
  9. Время завершения загрузки документа:Это когда клиентский браузер считает страницу загруженной.

3.1.3 Проблемы с HTTP/1

Проблема HTTP/1, естественно, является основной проблемой, которую должен решить HTTP/2.

1. Блокировка начала очереди

Браузеры редко получают только один ресурс с одного доменного имени и обычно ожидают получения множества ресурсов одновременно. h1 имеет функцию конвейерной обработки, которая позволяет отправлять группу запросов одновременно, но получать ответы только в том порядке, в котором они были отправлены. Конвейерная обработка страдает от проблем с совместимостью и развертыванием и не имеет большого практического значения. Во время процесса запрос-ответ, если возникнет какое-либо условие, вся оставшаяся работа будет заблокирована после этого запроса-ответа. Это «блокировка начала строки», которая блокирует сетевой трафик и рендеринг веб-страницы до тех пор, пока она не перестанет отвечать. Чтобы предотвратить эту проблему, современные браузеры открывают до 6 соединений для одного доменного имени и отправляют отдельные запросы через каждое соединение. Это обеспечивает некоторую степень параллелизма, но каждое соединение все равно будет затронуто.

2. Неэффективное использование TCP

Концепция протокола управления передачей (TCP): очень консервативные предположения и возможность применять одинаково справедливое отношение к различному сетевому трафику. Основная концепция заключается в том, чтобы задействовать окно перегрузки (окно перегрузки). «Окно перегрузки» относится к подтверждению количества TCP-пакетов до того, как пакет отправителя может быть выдан получателю. Например, если окно перегрузки равно 1, то отправитель отправляет пакет данных, только получатель, подтвердивший этот пакет, может отправить следующий.

TCP имеет концепцию, называемуюмедленный старт(Медленный старт), который используется для изучения соответствующего размера окна перегрузки, соответствующего текущему соединению. Цель дизайна медленного старта состоит в том, чтобыПозвольте новому соединению разобраться в текущей ситуации в сети, чтобы и дальше не добавлять хаоса в и без того перегруженную сеть.. Это позволяет отправителю отправлять 1 дополнительный неподтвержденный пакет после получения каждого подтверждения. Это означает, что новое соединение может отправить 2 пакета после получения 1 ответа подтверждения, 4 после получения 2 ответов подтверждения и так далее. Эта геометрическая прогрессия вскоре достигнет верхнего предела количества пакетов, отправляемых протоколом, и в это время соединение войдет в стадию предотвращения перегрузки.

TCP拥塞控制

Этот механизм требует нескольких запросов данных туда и обратно, чтобы узнать оптимальный размер окна перегрузки. Однако при решении проблем с производительностью всего несколько циклов передачи данных также являются очень ценными временными затратами. Если вы установите для пакета нижнее максимальное ограничение в 1460 байт, вы сможете отправить только 5840 байт (при условии, что окно перегрузки равно 4), а затем вам нужно будет дождаться ответа с подтверждением. В идеале для передачи всей страницы требуется около 9 запросов туда и обратно. Кроме того, браузеры обычно открывают 6 одновременных подключений для одного и того же доменного имени, и каждое подключение неизбежно корректирует окно перегрузки.

Традиционные реализации TCP используют алгоритм управления перегрузкой для настройки обратной связи на основе потери пакетов. Если подтверждения пакетов потеряны, алгоритм сокращает окно перегрузки. Это похоже на возню в темной комнате и изменение направления, если наши ноги ударяются о стол. Он даже полностью сбрасывает окно перегрузки и повторно входит в фазу медленного старта, если обнаруживает тайм-аут, т. е. ожидающие ответы не приходят вовремя. Новый алгоритм учитывает другие факторы, такие как задержка, чтобы обеспечить лучший механизм обратной связи.

Как упоминалось ранее, поскольку h1 не поддерживает мультиплексирование, браузеры обычно открывают 6 одновременных подключений для указанного доменного имени. Это означает, что колебания окна перегрузки также происходят 6 раз параллельно. Протокол TCP гарантирует, что эти соединения будут работать, но не может гарантировать, что их производительность будет оптимальной.

3. Раздутые заголовки сообщений

Хотя h1 предоставляет механизм для сжатия запрошенного содержимого, заголовок сообщения не может быть сжат. Заголовок сообщения нельзя игнорировать, хотя он намного меньше ресурса ответа, он может занимать подавляющую часть (а иногда и весь) запроса. Еще больше, если считать куки.

Отсутствие сжатия заголовков сообщений также может легко привести к тому, что клиенты достигнут предела пропускной способности, особенно для каналов с низкой пропускной способностью или сильно загруженных каналов. «Эффект стадиона» — классический пример. Если тысячи людей одновременно находятся в одном месте (например, на крупном спортивном мероприятии), пропускная способность беспроводной сотовой сети может быстро снизиться. В это время, если вы можете сжать заголовок запроса и уменьшить размер запроса, вы можете снизить нагрузку на полосу пропускания и снизить общую нагрузку на систему.

4. Ограниченные настройки приоритета

Если браузер открывает несколько сокетов для указанного доменного имени (каждый из которых страдает от проблемы блокировки заголовка строки) и начинает запрашивать ресурсы, браузер может указать приоритет ограниченным образом: либо инициировать запрос, либо нет. . Однако некоторые ресурсы на веб-странице важнее других, что неизбежно увеличивает эффект очереди ресурсов. Это связано с тем, что браузер откладывает запрос других ресурсов, чтобы сначала запросить ресурсы с высоким приоритетом. Однако после получения ресурса с высоким приоритетом браузер не будет инициировать новый запрос ресурса в процессе обработки, поэтому сервер не может использовать это время для отправки ресурса с низким приоритетом, и поэтому общее время загрузки страницы увеличивается. Также бывает, что ресурс с высоким приоритетом обнаруживается браузером, но из-за того, как браузер его обрабатывает, он ставится в очередь после извлечения ресурса с низким приоритетом.

5. Сторонние ресурсы

Многие ресурсы, запрошенные на веб-страницах сегодня, полностью независимы от контроля сервера сайта, и мы называем эти сторонние ресурсы. Половина времени загрузки современных веб-страниц часто тратится на сторонние ресурсы. Хотя существует много техник, чтобы минимизировать влияние сторонних ресурсов на производительность страницы, многие сторонние ресурсы находятся за пределами управления веб-разработчиками, поэтому, вероятно, что некоторые из них имеют плохую производительность, задержку или даже блокирующие рендеринг страницы. Отказ Унишительно, H2 тоже ничего не делает.

3.2 Технология оптимизации веб-производительности

В 2010 году Google рассматривал веб-производительность как один из важных факторов, влияющих на результаты поиска страниц, и показатели производительности начали играть определенную роль в поисковой системе. Для многих веб-страниц большая часть времени браузера используется не для отображения основного содержимого (обычно HTML) с веб-сайта, а скорее для запроса всех ресурсов и отображения страницы.

В результате веб-разработчики все больше внимания уделяют повышению производительности веб-сайтов за счет сокращения сетевых задержек на стороне клиента и оптимизации производительности рендеринга страниц.

3.2.1 Лучшие практики веб-производительности

1. Оптимизация DNS-запросов

Прежде чем можно будет установить соединение с хостом службы, доменное имя должно быть разрешено; тогда чем быстрее будет разрешено разрешение, тем лучше. Вот несколько методов:

  1. Ограничьте количество разных доменных имен. Конечно, это обычно вне вашего контроля
  2. Гарантированная низкая задержка парсинга. Поймите структуру вашей инфраструктуры службы DNS, а затем регулярно отслеживайте время разрешения во всех регионах, где распределены ваши конечные пользователи.
  3. Используйте директивы предварительной выборки DNS в HTML или ответах. Таким образом, пока HTML загружается и обрабатывается, инструкция prefetch может начать разбор доменного имени, указанного на странице.
 <link rel="dns-prefetch" href="//ajax.googleapis.com">
2. Оптимизируйте TCP-соединение

Как упоминалось ранее в этой главе, открытие нового соединения — процесс, требующий много времени. Если соединение использует TLS (а так и должно быть), накладные расходы будут выше. Способы уменьшить эти накладные расходы следующие:

  1. Прекращайте и отвечайте раньше. С помощью CDN на запросы можно отвечать на граничных конечных точках, которые находятся очень близко к запрашивающему пользователю, поэтому соединения могут быть разорваны, что значительно снижает задержку связи для установления новых соединений.
  2. Внедрите новейшие передовые методы TLS для оптимизации HTTPS.
  3. использоватьpreconnectкоманда, соединение устанавливается до того, как оно будет использовано, так что время соединения не нужно учитывать на критическом пути потока обработки,preconnectНе только разрешает DNS, но также устанавливает TCP-подключения и протоколы TLS (при необходимости).
<link rel="preconnect" href="//fonts.example.com" crossorigin>

Если с одного и того же доменного имени запрашивается большое количество ресурсов, браузер автоматически открывает одновременные подключения к серверу, чтобы избежать узких мест при получении ресурсов. Хотя большинство браузеров в настоящее время поддерживают 6 или более одновременных подключений, вы не можете напрямую контролировать количество одновременных подключений браузера для одного и того же доменного имени.

3. Избегайте редиректов

Перенаправления обычно инициируют подключения к дополнительным доменным именам. В мобильной сети дополнительная переадресация может добавить сотни миллисекунд к задержке, что плохо сказывается на пользовательском опыте и в конечном итоге влияет на бизнес на сайте. Простое решение — полностью исключить перенаправления, потому что часто для перенаправления нет уважительной причины. Если их нельзя устранить напрямую, у вас есть два варианта:

  1. Используйте CDN вместо клиента для перенаправления в облаке
  2. Если это перенаправление того же доменного имени, используйте правило перезаписи на веб-сервере, чтобы избежать перенаправления.
4. Кэширование на стороне клиента

Нет ничего быстрее, чем получение ресурсов непосредственно из локального кеша, потому что для этого вообще не требуется подключение к сети.

  1. Так называемый чисто статический контент, такой как изображения или версионные данные, может постоянно кэшироваться на стороне клиента. Даже если для TTL установлено большое время, скажем, месяц, оно все равно истечет из-за ранней очистки или очистки кэша, после чего клиенту, возможно, придется снова получить данные из источника.
  2. CSS/JS и активы персонализации, время кэширования примерно в два раза превышает среднее время сеанса (взаимодействия). Этого периода времени достаточно, чтобы гарантировать, что большинство пользователей смогут извлекать ресурсы локально при просмотре сайта, и достаточно мало, чтобы почти гарантировать, что самый последний контент будет извлечен из сети в следующем сеансе.

Управление кешем и ключи можно указать через HTTP-заголовки.max-age(в секундах) илиexpiresстолица.

5. Кэширование на границе сети

Личная информация (пользовательские настройки, финансовые данные и т. д.) никогда не должна кэшироваться на границе сети, поскольку ею нельзя поделиться. Ресурсы, чувствительные ко времени, также не следует кэшировать, например котировки акций в торговых системах реального времени. Тем не менее, все остальное кэшируется, даже если только на несколько секунд или минут. Для тех ресурсов, которые не обновляются часто, но должны обновляться сразу же после внесения изменений, таких как важные новости, можно использовать механизм очистки кэша, предоставляемый основными поставщиками CDN. Этот режим называется «Hold til Told» (Держать до справки), что означает, что эти ресурсы постоянно кэшируются и удаляются после получения уведомления.

6. Условное кэширование

Если срок жизни кэша истекает, клиент делает запрос на сервер. В большинстве случаев полученный ответ фактически совпадает с кешированной версией, и повторно загружать контент, который уже находится в кеше, нерационально. HTTP предоставляет механизм условного запроса, и клиент может запросить сервер эффективным способом: «Если содержимое изменилось, пожалуйста, верните само содержимое; в противном случае прямо скажите мне, что содержимое не изменилось. 』Когда ресурсы не меняются часто, использование условных запросов может значительно сэкономить пропускную способность и производительность, однако также очень важно обеспечить быстрый доступ к последним версиям ресурсов. Вы можете использовать условное кэширование следующими способами.

  1. Он содержит заголовок HTTP в запросеLast-Modified-Since. Сервер возвращает полный контент только в том случае, если последний контент был обновлен после даты, указанной в заголовке; в противном случае он возвращает только код ответа 304 с новой отметкой времени в заголовке ответа.Dateполе.
  2. Включите код проверки объекта в тело запроса илиETag; он однозначно идентифицирует запрошенный ресурс. ETag предоставляется сервером и встраивается в заголовок ответа ресурса. Сервер сравнивает текущиеETagполучено в заголовке запросаETag, если они совпадают, вернуть только код ответа 304; в противном случае вернуть полное содержимое.

Как правило, большинство веб-серверов используют эти методы для изображений и CSS/JS, но вы можете использовать их и для других ресурсов.

7. Сжатие и упрощение кода

Весь текстовый контент (HTML, JS, CSS, SVG, XML, JSON, шрифты и т. д.) можно сжать и минимизировать. В сочетании эти два подхода могут значительно уменьшить размер ресурсов. Меньшее количество байтов соответствует меньшему количеству запросов и ответов, что означает более короткое время запроса.

Минификация (обфускация) — это процесс удаления всего неосновного контента из текстового ресурса. Часто удобочитаемость для человека и обслуживание вызывают беспокойство, в то время как браузеры не заботятся о читабельности, а отказ от читаемости кода экономит место. В очень упрощенном виде сжатие может еще больше уменьшить количество байтов. Он уменьшает размер ресурсов с помощью алгоритма восстановления без потерь. Вы можете сэкономить 90% размера, если сервер сделает сжатие перед отправкой ресурса.

8. Избегайте блокировки CSS/JS

Перед отрисовкой первого пикселя на экране браузер должен убедиться, что CSS полностью загружен. Хотя препроцессор браузера достаточно умен, чтобы запрашивать CSS, необходимый для всей страницы, как можно раньше, по-прежнему рекомендуется размещать запросы ресурсов CSS в верхней части страницы, в теге заголовка документа и в до того, как будут запрошены и обработаны какие-либо JS или изображения.

По умолчанию, если JS находится в HTML, он будет запрошен, проанализирован и затем выполнен. Пока браузер не завершит обработку этого JS, он не позволит загружать и отображать любые последующие ресурсы. Однако в большинстве случаев такое поведение блокировки по умолчанию вызывает ненужные задержки и даже создает единую точку отказа. Чтобы смягчить потенциальное влияние блокировки JS, ниже рекомендуются разные стратегии для ваших собственных ресурсов (которые вы можете контролировать) и сторонних ресурсов (которые вы не можете контролировать).

  1. Периодически проверяйте использование этих ресурсов. Со временем веб-страница может продолжать загружать какой-то JS, который больше не нужен, и лучше всего от него избавиться.
  2. Если порядок выполнения JS не имеет значения и должен бытьonloadзапустить до того, как событие будет запущено, вы можете установитьasyncсвойства, например:
    <script async src="/js/myfile.js">
    
    Простая загрузка JS параллельно с разбором HTML может значительно улучшить общий пользовательский опыт. Используйте с осторожностьюdocument.writeинструкции, так как она может прервать выполнение страницы, ее необходимо тщательно протестировать.
  3. Если важен порядок выполнения JS и вы можете позволить запускать скрипты после загрузки DOM, используйте атрибут defer. так
    <script defer src="/js/myjs.js">
    
  4. JS-скрипт не влияет на начальное отображение страницы, вы должны запросить (обработать) его после того, как событие загрузки вызовет его.
  5. Если вы не хотите задерживать главную страницуonloadсобытия, которые можно рассматривать черезiframeПолучите JS, так как его обработка не зависит от главной страницы. Однако, поiframeСкачанный JS не может получить доступ к элементам на главной странице.
9. Оптимизация изображения

Для большинства веб-сайтов возрастает важность и вес изображений. Поскольку изображения доминируют на большинстве современных веб-сайтов, их оптимизация даст наибольшую отдачу от производительности. Целью всех оптимизаций изображения является передача наименьшего количества байтов при сохранении заданного визуального качества.

  1. Метаинформация изображения, такая как информация о геолокации объекта, отметка времени, размер и информация о пикселях, обычно содержится в двоичных данных и должна быть удалена перед отправкой клиенту (не забудьте сохранить информацию об авторских правах и описании цвета). Эта обработка без потерь может выполняться во время генерации изображения. Для изображений PNG типичная экономия места составляет около 10%.
  2. Перегрузка изображения — это когда изображение автоматически сжимается браузером либо потому, что исходный размер превышает размер отпечатка в видимой области браузера, либо потому, что пиксели превышают возможности дисплея устройства. Это не только пустая трата полосы пропускания, но также потребляет значительное количество ресурсов ЦП, которые иногда являются большим преимуществом на портативных устройствах. Чтобы устранить перегрузку изображениями, можно использовать технические средства для предоставления обрезанных изображений (с точки зрения размера и качества) в зависимости от устройства пользователя, условий сети и ожидаемого качества изображения.

3.2.2 Антишаблоны

HTTP/2 будет открывать только одно соединение для каждого доменного имени, поэтому некоторые приемы в HTTP/1.1 будут для него только контрпродуктивными.

Подробности см. в разделе 6.7.

3.3 Резюме

HTTP/1.1 породил множество инструментов и ноу-хау для оптимизации производительности, которые могут помочь нам понять Web и его внутреннюю реализацию. Одной из целей HTTP/2 является устранение многих, но не всех, этих уловок.

4. Миграция HTTP/2

Прежде чем переходить на HTTP/2, вы должны принять во внимание:

  1. Поддержка браузера для h2
  2. Возможность перехода на TLS (HTTPS)
  3. Оптимизируйте свой сайт на основе h2 (может быть контрпродуктивно для h1)
  4. Сторонние ресурсы на Сайте
  5. Поддерживать совместимость с более ранними версиями клиентов

4.1 Поддержка браузера

Любой клиент, который не поддерживает h2, просто вернется к h1 и по-прежнему будет иметь доступ к инфраструктуре вашего сайта.

4.2 Переход на TLS

Все основные браузеры могут получить доступ к h2 только через TLS (т. е. HTTPS-запросы).

4.3 Отказ от оптимизаций для HTTP/1.1

Веб-разработчики приложили много усилий, чтобы получить максимальную отдачу от h1, и придумали такие приемы, как слияние ресурсов, разделение доменов, минимальное упрощение, домены с отключенными файлами cookie, спрайты и многое другое. Итак, вы можете быть удивлены, узнав, что некоторые из этих практик становятся анти-паттернами в h2. Например, слияние ресурсов (объединение нескольких файлов CSS/JS в один) не позволяет браузеру выполнять несколько запросов. Для h1 это важно, потому что делать запрос дорого, но в мире h2 эта часть сильно оптимизирована. Результатом отказа от слияния ресурсов может быть то, что стоимость выполнения запроса для одного ресурса будет низкой, но на стороне браузера может выполняться более детальное кэширование.

Подробности см. в разделе 6.7.

5. Протокол HTTP / 2

В этой главе будет всесторонне рассмотрена базовая работа HTTP/2, подробно рассмотрены кадры, передаваемые уровнем данных, и то, как они передаются.

5.1 Уровни HTTP/2

HTTP/2 можно условно разделить на две части.

  1. Обрамляющий слойТо есть основная часть возможности мультиплексирования h2, основная цель - передача HTTP
  2. данные или http слойСодержит то, что традиционно считается HTTP, и связанные с ним данные и обратно совместимо с HTTP/1.1.

H2 На некоторые особенности необходимо обратить внимание:

  1. бинарный протокол: уровень кадров h2 представляет собой двоичный протокол на основе кадров, который удобен для машинного анализа, но его трудно идентифицировать невооруженным глазом.
  2. сжатие заголовка: Просто использовать бинарный протокол недостаточно, заголовок h2 также глубоко сжат. Это значительно уменьшит количество избыточных байтов при передаче.
  3. мультиплексирование: при просмотре соединения на основе транспорта h2 в инструменте отладки вы обнаружите, что запрос и ответ переплетаются.
  4. зашифрованная передача: Большая часть данных, передаваемых онлайн, зашифрована, поэтому их будет сложнее прочитать в середине.

5.2 Подключение

В отличие от h1, который полностью не имеет состояния, h2 объединяет элементы канального уровня, от которых зависят кадр и передаваемый им поток, включая как настройки канального уровня, так и таблицы заголовков. Тем не менее, в отличие от предыдущих версий HTTP, каждое соединение h2 имеет некоторые накладные расходы. Причина этого в том, что выгоды намного превышают затраты.

Во время соединения HTTP/2 предоставляет два механизма для обнаружения протокола:

  1. В случае незашифрованного соединения клиент будет использовать заголовок Upgrade, чтобы указать, что он ожидает использовать h2. Если сервер также может поддерживать h2, он вернет ответ 101 Switching Protocols. Это добавляет полный цикл связи запрос-ответ.
  2. Иначе обстоит дело, если соединение основано на TLS. Клиент устанавливает расширение ALPN (согласование протокола прикладного уровня) в сообщении ClientHello, чтобы указать, что он ожидает использовать протокол h2, и сервер отвечает таким же образом. При таком использовании h2 согласовывается во время создания рукопожатия TLS и не требует избыточной сетевой связи.

В процессе формулировки протокола очень рано была удалена десятичная точка, что указывает на то, что будущая версия HTTP не может гарантировать обратную совместимость семантики, то есть только HTTP/2 не имеет HTTP/2.0, HTTP/2.2

5.3 кадра

HTTP/2 — это протокол на основе фреймов, который используется для инкапсуляции важной информации, чтобы синтаксический анализатор протокола мог легко читать, анализировать и восстанавливать информацию. Напротив, h1 не основан на кадрах, а ограничен текстом. Таким образом, синтаксический анализ запроса или ответа h1 может иметь следующие проблемы:

  1. Одновременно может обрабатываться только один запрос или ответ, и синтаксический анализ нельзя остановить, пока он не будет завершен.
  2. Невозможно предсказать, сколько памяти потребуется для синтаксического анализа. Это поднимает целую кучу вопросов: какой размер буфера вы хотите прочитать в строку; что произойдет, если строка слишком длинная; следует ли увеличить и перераспределить память или вернуть ошибку 400?

С другой стороны, с кадрами программа, обрабатывающая протокол, заранее знает, что будет получено. На следующем рисунке показана структура фрейма HTTP/2.

HTTP/2 帧结构

Первые 9 байтов согласуются для каждого кадра. Вам нужно только прочитать эти байты при разборке, чтобы точно узнать, сколько байтов ожидать во всем кадре. Каждое из этих полей описано ниже

имя длина описывать
Length 3 байта Указывает длину полезной нагрузки кадра (диапазон значений: 2^14~2^24-1 байт). Обратите внимание, что 214 байт — это максимальный размер кадра по умолчанию, если требуется кадр большего размера, его необходимо установить в кадре НАСТРОЙКИ.
Type 1 байт текущий тип кадра
Flags 1 байт Идентификация конкретного типа кадра
R 1 человек Зарезервированный бит, не устанавливайте, иначе это может привести к серьезным последствиям
Stream Identifier 31 бит Уникальный идентификатор для каждого потока
Frame Payload переменная длина Фактическое содержимое кадра, длина задается в поле Длина

По сравнению с h1, который опирается на разделители, у h2 есть еще одно большое преимущество: если вы используете h1, вам нужно отправить предыдущий запрос или ответ перед отправкой следующего; поскольку h2 обрамлен, запросы и ответы могут чередоваться или даже больше мультиплексироваться . Мультиплексирование помогает решить такие проблемы, как блокировка начала строки.

h2 имеет десять различных типов фреймов:

имя ID (Type) описывать
DATA 0x0 Кадр данных, основное содержимое транспортного потока
HEADERS 0x1 Кадр заголовка, содержащий заголовки HTTP и необязательный параметр приоритета.
PRIORITY 0x2 Кадр приоритета, указывающий или изменяющий приоритет и зависимости потока
RST_STREAM 0x3 Кадр завершения потока, который позволяет одному концу остановить поток (обычно из-за ошибки).
SETTINGS 0x4 Установка фреймов, согласование параметров уровня соединения
PUSH_PROMISE 0x5 Пуш-кадры, подсказывающие клиенту, что сервер хочет что-то подтолкнуть.
PING 0x6 Кадры PING для проверки доступности соединения и задержки приема-передачи (RTT)
GOAWAY 0x7 Кадр GOAWAY, сообщающий другому концу, что текущий конец закончился
WINDOW_UPDATE 0x8 Кадр обновления окна, согласовывающий, сколько байтов получит один конец (для управления потоком)
CONTINUATION 0x9 Кадр продолжения для расширения блока HEADER

Расширенная рамка: HTTP/2 имеет встроенную возможность обработки новых типов фреймов, называемых расширенными фреймами. Опираясь на этот механизм, разработчики клиентов и серверов могут экспериментировать с новыми типами фреймов, не разрабатывая новые протоколы. Согласно спецификации, любые фреймы, не распознанные клиентом, отбрасываются, поэтому новые фреймы в сети не влияют на основной протокол. Конечно, могут возникнуть проблемы, если ваше приложение полагается на новые фреймы, а промежуточные прокси их отбрасывают.

5.4 Потоки

Поток в спецификации HTTP/2: независимый двунаправленный обмен последовательностью кадров через соединение HTTP/2. Вы можете думать о потоке как о серии кадров по соединению, которые передают пару сообщений запрос/ответ. Если клиент хочет сделать запрос, он запускает новый поток, и сервер отвечает на этот поток. Это похоже на процесс запроса и ответа h1, разница в том, что из-за кадрирования несколько запросов и ответов могут чередоваться, не блокируя друг друга. Идентификатор потока (байты 6–9 заголовка кадра) используется для идентификации потока, которому принадлежит кадр.

После того, как соединение h2 между клиентом и сервером установлено, отправивHEADERSкадр, чтобы начать новый поток, если заголовок должен охватывать несколько кадров, он также может быть отправленCONTINUATIONРамка.

5.4.1 Сообщения

HTTP-сообщения обычно относятся к HTTP-запросам или ответам. Сообщение состоит как минимум из кадра HEADERS (используется для инициализации потока) и может дополнительно содержатьCONTINUATIONа такжеDATAрамы и другиеHEADERSРамка. На следующем рисунке показан пример потока обычного запроса GET.

普通 GET 请求的示例流程

Одно из основных различий между POST и GET заключается в том, что запрос POST обычно содержит большой объем данных, отправляемых клиентом. На следующем рисунке показано, как может выглядеть каждый кадр, соответствующий сообщению POST.

普通 POST 请求的示例流程

Запрос и ответ h1 разделены на две части: заголовок сообщения и тело сообщения, аналогично запрос и ответ h2 разделены на две части.HEADERSрамка иDATAРамка. Следует отметить следующие различия между сообщениями HTTP/1 и HTTP/2.

  1. все в заголовке:h1 Разделите сообщение на две части: строку запроса/статуса и заголовок. h2 устраняет это различие и превращает строки в волшебные псевдозаголовки.
  2. Нет фрагментированного кодирования: фрагментация используется только при отправке данных другой стороне без предварительного знания длины данных. В h2, который использует фреймы в качестве основного протокола, фрагментация больше не требуется.
  3. Не более 101 ответа: ответ протокола переключения является пограничным приложением h1. Вероятно, его наиболее распространенное использование сегодня — это обновление до соединения WebSocket. ALPN обеспечивает более четкий путь согласования протокола с меньшими накладными расходами в оба конца.

5.4.2 Управление потоком

Одной из новых функций h2 является управление потоком на основе потока. В h1, пока клиент может его обработать, сервер будет отправлять данные как можно быстрее, h2 предоставляет клиенту возможность регулировать скорость передачи, и сервер также может регулировать скорость передачи.

WINDOW_UPDATEФреймы используются для выполнения функций управления потоком и могут действовать в одном потоке (указать конкретныйStream Identifier) также может действовать на все соединение (Stream Identifier0x0), толькоDATAКадры подлежат управлению потоком. После инициализации окна трафика окно трафика уменьшается на столько, сколько отправляется нагрузка.Если окно трафика недостаточно, его нельзя отправить.WINDOW_UPDATEФреймы могут увеличивать размер окна трафика. Когда поток установлен, размер окна по умолчанию составляет 65535 (2^16-1) байт.

5.4.3 Приоритет

Последней важной особенностью потоков являются зависимости.

Современные браузеры пытаются получить ресурсы в оптимальном порядке, чтобы оптимизировать производительность страницы. В отсутствие мультиплексирования ему необходимо дождаться завершения предыдущего ответа, прежде чем он сможет выдать запрос на новый объект. Благодаря возможности мультиплексирования h2 клиент может делать запросы ко всем ресурсам сразу, а сервер может немедленно начать обработку этих запросов. Проблема в том, что браузер теряет политику приоритета запросов ресурсов по умолчанию в эпоху h1. Если предположить, что сервер получает 100 запросов одновременно, не определяя, какой из них важнее, он будет отправлять каждый ресурс почти одновременно, а второстепенные элементы будут влиять на передачу критических элементов.

h2 решает указанную выше проблему за счет потоковых зависимостей. пройти черезHEADERSрамка иPRIORITYFrames клиент может явно сообщать серверу, что ему нужно, и в каком порядке ему нужны эти ресурсы. Это достигается путем объявления дерева зависимостей и относительных весов внутри дерева.

  1. зависимостиПредоставляет клиенту возможность сообщить серверу, что некоторые объекты должны быть переданы в первую очередь, указав, что некоторые объекты имеют зависимости от других.
  2. ВесаПусть клиент сообщает серверу, как расставлять приоритеты для объектов с общими зависимостями.

Потоки могут быть помечены как зависимые от других потоков, и текущий поток обрабатывается после завершения зависимого потока. За каждой зависимостью следует вес, число, используемое для определения относительной доли доступных ресурсов, которые могут быть выделены в зависимости от того же потока.

В другое время вы также можете пройтиPRIORITYФреймы регулируют приоритет потока.

Цель установки приоритетов состоит в том, чтобы конечная точка выразила ожидаемое поведение однорангового узла при распределении ресурсов между несколькими параллельными потоками. Что еще более важно, когда пропускная способность отправки ограничена, можно использовать приоритет для выбора потока для отправки кадров.

5.5 Отправка сервера

Лучший способ повысить производительность отдельного объекта — поместить его в кеш браузера до того, как он будет использован. Это именно то, для чего нужен h2 server push.

5.5.1 Толкающие объекты

Если сервер решает передать объект (называемый в RFC «ответом на отправку»), он создаетPUSH_PROMISEРамка. Этот фрейм обладает многими важными свойствами:

  1. PUSH_PROMISEИдентификатор потока (Promised Stream ID) в заголовке кадра используется для ответа на связанный запрос. Нажатый ответ должен соответствовать запросу, отправленному клиентом. Если браузер запрашивает основную HTML-страницу, если объект JavaScript, используемый этой страницей, должен быть отправлен, сервер создаст идентификатор потока, соответствующий запросу.PUSH_PROMISEРамка.
  2. PUSH_PROMISEБлок заголовка кадра аналогичен блоку заголовка, отправляемому, когда клиент запрашивает отправку объекта. Таким образом, у клиента есть способ безопасно проверить запрос, который будет отправлен.
  3. Отправляемый объект должен быть гарантированно кэшируемым.
  4. :methodЗначение заголовка должно быть безопасным. Безопасные методы — это те, которые являются идемпотентными, что является хорошим способом не изменять какое-либо состояние. Например, запрос GET считается идемпотентным, поскольку обычно он просто извлекает объект, а запрос POST считается неидемпотентным, поскольку он может изменить состояние на стороне сервера.
  5. В идеале,PUSH_PROMISEКадры должны отправляться раньше, до того, как клиент получитDATAРамка. Предположим, сервер хочет отправитьPUSH_PROMISEперед отправкой полного HTML клиент может получитьPUSH_PROMISEРанее выдавался запрос на этот ресурс. h2 достаточно надежен, чтобы изящно решать такие проблемы, но все же является некоторой тратой времени.
  6. PUSH_PROMISEВо фрейме будет указан идентификатор потока, с которым будет отправлен ответ

Если клиентPUSH_PROMISEЕсли Вас не устраивает какой-либо элементRST_STREAM), или отправитьPROTOCOL_ERROR(существуетGOAWAYРамка). Обычным случаем является то, что объект уже существует в кэше.

Предполагая, что клиент не отклоняет отправку, сервер продолжит процесс отправки, используяPUSH_PROMISEУкажите поток, соответствующий идентификатору, для отправки объекта

服务端推送消息处理

5.5.2 Выбор ресурсов для отправки

Если сервер получает запрос на страницу, он должен решить, отправить ли ресурс на страницу или подождать, пока клиент запросит его. В процессе принятия решений необходимо учитывать следующие аспекты

  1. Вероятность того, что ресурс уже находится в кеше браузера
  2. Приоритет этих ресурсов с точки зрения клиента (см. Раздел 5.4.3)
  3. Доступная пропускная способность и другие подобные ресурсы, влияющие на способность клиента получать push-уведомления.

Если сервер выбран правильно, это действительно может помочь улучшить общую производительность страницы, в противном случае это ухудшит производительность страницы.

5.6 Сжатие заголовка

Средняя современная веб-страница имеет много запросов с небольшим количеством нового контента между этими запросами, что является огромной тратой.

Список заголовков — это набор из нуля или более полей заголовков. При отправке по соединению список заголовков сериализуется в блок заголовков с помощью алгоритма сжатия (т. е. HPACK ниже), GZIP не используется, поскольку существует риск утечки зашифрованной информации. HPACK — это схема сжатия с поиском по таблице, в которой используется кодирование Хаффмана для достижения степени сжатия, близкой к GZIP.

Затем сериализованный блок заголовка разделяется на одну или несколько последовательностей байтов, называемых фрагментами блока заголовка, и передается черезHEADERS,PUSH_PROMISE,илиCONTINUATIONрама для передачи полезной нагрузки.

Предположим, что клиент отправляет следующие заголовки запроса по порядку:

Header1: foo
Header2: bar
Header3: bat

Когда клиент отправляет запрос, в блоке данных заголовка может быть указан конкретный заголовок и его значение, которое должно быть проиндексировано. Он создаст таблицу:

показатель имя заголовка стоимость
62 Header1 foo
63 Header2 bar
64 Header3 bat

Если сервер прочитает эти заголовки запроса, он также создаст таблицу. Когда клиент отправляет следующий запрос, если заголовки совпадают, он может отправить его напрямую:62 63 64, сервер просматривает предыдущую таблицу и восстанавливает числа до полного заголовка, соответствующего индексу. Каждое соединение в механизме сжатия заголовков поддерживает свое собственное состояние.

Реализация HPACK намного сложнее, например:

  1. Инициатор запроса и ответчик ведут по две таблицы каждый. Одна из них — динамическая таблица, которая создается так же, как описано выше. Другая представляет собой статическую таблицу, состоящую из комбинаций ключ-значение 61 наиболее распространенного заголовка. Например:method: GETВ статической таблице индекс равен 2. По соглашению статическая таблица содержит 61 запись, поэтому номера индексов в приведенном выше примере начинаются с 62.
  2. Существует множество правил, регулирующих индексацию полей:
    1. Отправить номер индекса и текстовое значение отправляются только текстовые значения, они не индексируются (для одноразовых или конфиденциальных заголовков)
    2. Отправляется имя заголовка индекса, а значение выражается в виде текста, но обработка индекса не выполняется (например,:path: /foo.html, значение которого каждый раз разное)
    3. Отправьте имя и значение проиндексированного заголовка (как во втором запросе в приведенном выше примере).
  3. Целочисленное сжатие с использованием схемы упаковки для максимальной эффективности использования пространства
  4. Используйте таблицу кодирования Хаффмана для дальнейшего сжатия строк

5.7 Онлайн-передача

Информация h2, передаваемая по сети, представляет собой сжатые двоичные данные.

простой GET-запрос

Ниже приведен простой запрос на получение h2.

:authority: www.akamai.com
:method: GET
:path: /
:scheme: https
accept: text/html,application/xhtml+xml,...
accept-language: en-US,en;q=0.8
cookie: sidebar_collapsed=0; _mkto_trk=...
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Macintosh;...

Ниже ответ от h2

:status: 200
cache-control: max-age=600
content-encoding: gzip
content-type: text/html;charset=UTF-8
date: Tue, 31 May 2016 23:38:47 GMT
etag: "08c024491eb772547850bf157abb6c430-gzip"
expires: Tue, 31 May 2016 23:48:47 GMT
link: <https://c.go-mpulse.net>;rel=preconnect
set-cookie: ak_bmsc=8DEA673F92AC...
vary: Accept-Encoding, User-Agent
x-akamai-transformed: 9c 237807 0 pmb=mRUM,1
x-frame-options: SAMEORIGIN

В этом ответе сервер указывает, что запрос был успешно принят (код состояния 200), и установлен файл cookie (заголовок файла cookie), указывающий, что возвращаемый контент сжат с использованием gzip (заголовок кодирования содержимого).

6. Производительность HTTP/2

HTTP/2 в большинстве случаев передает веб-страницы быстрее, чем HTTP/1.1.

  1. Для страниц с большим количеством небольших ресурсов загрузка h2 занимает меньше времени, чем h1. Это связано с тем, что в h1 (с 6 TCP-соединениями) сервер может отправлять только 6 ресурсов параллельно (из-за блокировки заголовка строки), в то время как несколько потоков в h2 могут совместно использовать соединения. Далее, по мере ухудшения состояния сети увеличивается время загрузки страницы (PLT) и по h1, и по h2, но h2 является односвязным, и если единственное соединение будет терять пакеты, это повлияет на всю работу.
  2. Для страниц с небольшим количеством больших ресурсов h1 работает лучше, чем h2, во всех сетевых условиях. Этот несколько неожиданный результат связан с начальным окном перегрузки. Если вы откроете 6 соединений, начальный размер окна перегрузки для h1 фактически в 6 раз больше, чем для h2. Итак, в начале сеанса окно соединения h2 не выросло до оптимального значения, но h1 уже смог быстрее передать больше данных. Эта проблема все еще решается, поскольку из-за нее начальное окно перегрузки слишком мало для h2, но слишком велико для h1. Кроме того, h2 более подвержен потере пакетов, чем h1.
  3. Для веб-страниц с очень большими ресурсами разницы нет. Недостаток начального окна перегрузки для h2 маскируется общей продолжительностью загрузки, и на этом этапе мультиплексирование больше не является преимуществом.

6.1 Реализация клиента

В одних и тех же сетевых условиях, при использовании разных клиентов-браузеров скорость загрузки страниц одного и того же веб-сайта может сильно различаться.

  1. Конкретная реализация протокола очень важна
  2. Не все запросы выиграют от HTTP/2 во всех случаях, и даже в этом случае URL-адреса, использующие h2, по-прежнему демонстрируют более высокий процент улучшения производительности, чем снижение производительности.

6.2 Задержка

Задержка — это время, необходимое пакету для перемещения от одной конечной точки к другой. Иногда он также представляет собой время, необходимое пакету для достижения получателя, а затем возвращения к отправителю, также известное как задержка приема-передачи (RTT), и длина обычно измеряется в миллисекундах.

На задержку влияет множество факторов, но два наиболее важных: расстояние между конечными точками и используемая среда передачи.

Сетевой кабель между двумя точками не будет прямым, а различные шлюзы, маршрутизаторы, коммутаторы и мобильные базовые станции (включая само серверное приложение) будут увеличивать задержку.

6.3 Потеря пакетов

Потеря пакетов происходит, когда пакеты, путешествующие по сети, не достигают пункта назначения, что обычно происходит из-за перегрузки сети.

Частая потеря пакетов повлияет на передачу страницы h2, в основном потому, что h2 открывает одно TCP-соединение.Каждый раз, когда происходит потеря/перегрузка пакетов, протокол TCP будет уменьшать окно TCP.

Если пакет отбрасывается в потоке TCP, все соединение h2 останавливается до тех пор, пока пакет не будет повторно отправлен и получен.

6.4 Отправка сервера

Проталкивание сервером позволяет серверу проталкивать ресурсы до запроса клиента. Тест показывает, что если толчок является разумным, время рендеринга страницы может быть сокращено на 20-50%.

Тем не менее, push также тратит впустую пропускную способность, потому что сервер может попытаться отправить ресурсы, которые уже кэшированы на стороне клиента, в результате чего клиент получит данные, которые ему не нужны. Клиент действительно может отправить кадр RST_STREAM, чтобы отклонить запрос сервера.PUSH_PROMISEкадр, ноRST_STREAMОн не придет сразу, поэтому сервер все равно отправит некоторую избыточную информацию.

Настоящая ценность проталкивания на стороне сервера реализуется, если пользователь может передать клиенту ключевые ресурсы CSS и JS, необходимые для рендеринга страницы, когда пользователь посещает страницу в первый раз. Однако для этого требуется, чтобы реализация на стороне сервера была достаточно умной, чтобы избежать «push-обещаний», конкурирующих за пропускную способность с основной передачей HTML-страницы.

В идеале отправка не инициируется до тех пор, пока сервер не обработает запрос тела HTML-страницы. Иногда серверу необходимо выполнить некоторую фоновую работу для создания HTML-страницы. В это время сервер занят, а клиент ждет, и это идеальное время, чтобы начать передавать клиенту необходимые ресурсы.

在后台处理的同时进行推送

6.5 Время первого байта

Время до первого байта (TTFB) используется для измерения скорости отклика сервера. — это время с момента, когда клиент инициирует HTTP-запрос, до момента, когда клиентский браузер получает первый байт ресурса. Он состоит из времени подключения к сокету, времени, необходимого для отправки HTTP-запроса, и времени, необходимого для получения первого байта страницы.

В h1 клиент последовательно запрашивает ресурсы при каждом соединении для одного доменного имени, и сервер последовательно отправляет эти ресурсы. Клиент будет запрашивать оставшиеся ресурсы только после получения ранее запрошенных ресурсов, а сервер будет продолжать отвечать на новые запросы ресурсов. Этот процесс повторяется до тех пор, пока клиент не получит все ресурсы, необходимые для отображения страницы.

В отличие от h1, при мультиплексировании h2 после загрузки HTML клиент параллельно отправляет большое количество запросов на сервер. По сравнению с h1 сумма времени для получения ответа на эти запросы, как правило, будет меньше; однако, поскольку запросы отправляются в одно и то же время, а время одного запроса начинается раньше, значение TTFB, подсчитываемое h2, будет меньше. быть выше.

HTTP/2 выполняет больше работы, чем h1, и его цель — повысить производительность в целом. Вот некоторые вещи, которых нет в h1, но реализованы в h2

  1. изменение размера окна
  2. Построение дерева зависимостей
  3. Поддерживать статическую/динамическую таблицу информации заголовка
  4. Сжать/распаковать заголовок
  5. Настройка приоритета (h2 позволяет клиенту несколько раз настроить приоритет одного запроса)
  6. Подготавливать потоки данных, которые еще не были запрошены клиентом.

На следующем рисунке показано сравнение времени загрузки одной и той же страницы с использованием h1 и h2. В целом, использование h2 лучше.

h1 与 h2 请求的时间序列

6.6 Сторонние ресурсы

Многие веб-сайты используют различные статистические, трекинговые, социальные и рекламные платформы, привлекая различные сторонние ресурсы.

  1. Сторонние запросы часто отправляются через разные доменные имена, так как браузерам необходимо разрешать DNS, устанавливать TCP-соединения и согласовывать TLS, это серьезно влияет на производительность;
  2. Потому что сторонние ресурсы под разными доменными именами, поэтому запрос не может быть протолкнут с сервера, ресурсная зависимость, приоритет запроса и т. д. свойства h2 выгодны. Эти функции предназначены только для запрошенного ресурса в том же домене;
  3. Вы не можете контролировать производительность сторонних ресурсов и не можете решать, будут ли они передаваться через h2;

6.7 Анти-шаблоны HTTP/2

Некоторые методы настройки производительности в h1 будут контрпродуктивными в h2. Ниже перечислены некоторые общие советы по оптимизации запросов h1 с учетом особенностей h2.

имя описывать Примечание
Консолидация ресурсов Объедините несколько файлов (JavaScript, CSS) в один файл, чтобы уменьшить количество HTTP-запросов. В HTTP/2 в этом нет необходимости, потому что запрос имеет меньшую стоимость в байтах и ​​время на передачу, хотя эта стоимость все еще существует.
чрезвычайно упрощенный Удалите бесполезный код из HTML, JavaScript, CSS и других файлов Отличная практика, чтобы держаться под HTTP/2
Разделение домена Распределяйте ресурсы по разным доменным именам, чтобы браузеры могли использовать больше сокетов. HTTP/2 был разработан, чтобы в полной мере использовать соединение с одним сокетом, и разделение доменного имени разрушило бы это намерение. Рекомендуется удалить разделение домена, но обратите внимание, что в поле примечаний после этой таблицы будут описаны различные сложности, связанные с этой проблемой.
Домены с отключенными файлами cookie Создайте отдельные домены для ресурсов, таких как изображения, которые не используют файлы cookie, чтобы минимизировать размер запроса. Следует избегать отдельного доменного имени для этих ресурсов (см. Разделение домена), но, что более важно, накладные расходы на файлы cookie значительно снижаются благодаря сжатию заголовков, обеспечиваемому HTTP/2.
Создание спрайтов Объедините несколько изображений в один файл и используйте CSS для управления частями, отображаемыми на веб-странице. Аналогично минимализации, за исключением того, что добиться этого эффекта с помощью CSS дорого; не рекомендуется использовать с HTTP/2.

6.7.1 Генерация спрайтов и слияние/встраивание ресурсов

Спрайтинг относится к объединению множества маленьких изображений в большое изображение, так что несколько элементов изображения могут быть покрыты только одним запросом. В HTTP/2 запросы на конкретные ресурсы больше не блокируются, и многие запросы могут обрабатываться параллельно; с точки зрения производительности генерация спрайтов спорна, потому что мультиплексирование и сжатие заголовков устраняют много накладных расходов на запросы.

Точно так же небольшие текстовые ресурсы, такие как JS и CSS, обычно объединяются в более крупный ресурс или встраиваются непосредственно в основной HTML-код, что также позволяет сократить количество соединений клиент-сервер. Проблема с этим подходом заключается в том, что эти маленькие CSS или JS сами по себе могут кэшироваться, но уж точно не в том случае, если они встроены в некэшируемый HTML. Для h2 все еще может иметь смысл объединить множество небольших JS-скриптов в один большой файл, поскольку это позволит улучшить сжатие и сэкономить ЦП.

6.7.2 Разделение доменного имени

Разделение домена позволяет использовать возможность браузера открывать несколько соединений для каждого доменного имени для параллельной загрузки ресурсов. Для сайтов с большим количеством небольших ресурсов обычной практикой является разделение доменов, чтобы воспользоваться тем фактом, что современные браузеры могут открывать 6 соединений на домен, чтобы использовать доступную пропускную способность.

Поскольку HTTP/2 использует мультиплексирование, разделение доменных имен не требуется, а вместо этого противоречит цели протокола. Лучший подход состоит в том, чтобы сохранить текущее разделение доменов, но убедиться, что домены используют один и тот же сертификат [подстановочный знак/сеть хранения данных (SAN)], а IP-адрес сервера и порт должны быть одинаковыми для слияния сети с браузерами), что экономит время, необходимое для установления соединения для одного доменного имени.

6.7.3 Домены, для которых файлы cookie отключены

В HTTP/1 заголовки запросов и ответов никогда не сжимаются. Со временем размер заголовка превысил размер одного TCP-пакета.cookieМожно сказать, обыденность. Поэтому накладные расходы на передачу информации заголовка туда и обратно между источником контента и клиентом могут вызвать значительные задержки.

Поэтому нет зависимости от картинок и тому подобногоcookieресурсы, отключитьcookie's доменное имя является разумным предложением.

Но в HTTP/2 заголовок сжимается, и и клиент, и сервер сохраняют «историю заголовка», чтобы избежать повторной передачи известной информации. Итак, если вы собираетесь реорганизовать свой сайт, вам не нужно думать об его отключении.cookieДоменное имя, которое может значительно снизить нагрузку.

Статические ресурсы также должны обслуживаться с одного и того же доменного имени; использование того же доменного имени, что и основная страница HTTP, устраняет дополнительные запросы DNS и (потенциально) соединения через сокеты, которые могут замедлить получение статических ресурсов. Размещение ресурсов, блокирующих рендеринг, под одним доменным именем также может повысить производительность.

6.7.4 Предварительная выборка ресурсов

Предварительная выборка ресурсов также является оптимизацией веб-производительности, которая побуждает браузер продолжать загрузку кэшируемых ресурсов, когда это возможно, и кэшировать их. Тем не менее, если браузер занят или загрузка ресурса занимает слишком много времени, запрос предварительной выборки будет проигнорирован. Предварительную выборку ресурсов можно реализовать, вставив теги ссылок в HTML:

<link rel="prefetch" href="/important.css">

Вы также можете использовать ответ HTTP вLinkстолица:Link: </important.css>; rel=prefetch

Предварительная выборка ресурсов имеет мало общего с проталкиванием на сервер, представленным h2. Серверная отправка используется для более быстрой доставки ресурсов в браузер, и одно из преимуществ предварительной выборки ресурсов по сравнению с отправкой заключается в том, что если ресурс уже находится в кеше, браузер не будет тратить время и пропускную способность на повторные запросы. Так что думайте об этом как о дополнительном инструменте для продвижения h2, а не как о функции, которая будет заменена.

6.8 Реальная производительность

Потеря сетевых пакетов — это источник жизненной силы h2, и один шанс потери пакетов приведет к тому, что все его оптимизации пропадут даром.

7. Реализация HTTP/2

7.1 Настольные веб-браузеры

Все браузеры должны использовать TLS (HTTPS) для транспорта HTTP/2, хотя на самом деле спецификация HTTP/2 не требует использования TLS. Причина этого:

  1. Из предыдущих экспериментов с WebSocket и SPDY, используяUpgradeЗаголовок, при обмене данными через порт 80 (порт HTTP с открытым текстом) такие факторы, как прерывание работы прокси-сервера в канале связи, вызовут очень высокий уровень ошибок. Если запрос выполняется на основе TLS через порт 443 (порт HTTPS), частота ошибок значительно снижается, а связь по протоколу также становится более лаконичной.
  2. Растет убеждение, что все должно быть зашифровано из соображений безопасности и конфиденциальности. HTTP/2 рассматривается как возможность продвижения зашифрованных коммуникаций в Интернете.

7.1.2 Отключить HTTP/2

В конце концов, HTTP/2 является новым, и многие браузеры теперь поддерживают включение или отключение h2.

7.1.3 Поддержка push-уведомлений сервера HTTP/2

Серверная загрузка — одна из самых захватывающих и сложных функций в h2, и теперь она поддерживается всеми основными браузерами.

7.1.4 Присоединиться к объединению

Если вам нужно создать новое соединение, а браузер поддерживает слияние соединений, то, подключив уже существующее перед мультиплексированием, можно улучшить производительность запроса. Это означает, что вы можете пропустить процесс рукопожатия TCP и TLS, первый запрос для повышения производительности нового доменного имени. Если браузер поддерживает слияние соединений, он сначала проверит, прежде чем открывать новое соединение, уже установлено ли соединение с тем же пунктом назначения.

Тот же пункт назначения конкретно относится к существующему соединению, сертификат которого действителен для нового доменного имени, которое может быть преобразовано в IP-адрес, соответствующий этому соединению. Если вышеуказанные условия соблюдены, браузер инициирует HTTP/2-запрос к доменному имени при установленном соединении.

7.2 Серверы, прокси и кэши

Если мы хотим передавать контент через h2, у нас есть несколько вариантов. Существует примерно два типа сетевых средств, поддерживающих HTTP/2.

веб сервер: обычно называются программы, которые обслуживают статический и динамический контент.

прокси/кеш: Как правило, между сервером и конечным пользователем может быть предусмотрено кэширование для снижения нагрузки на сервер или выполнения дополнительной обработки. Многие прокси-серверы также могут выступать в качестве веб-серверов.

При выборе сервера HTTP/2 нам необходимо проверить и оценить некоторые ключевые моменты. В дополнение к базовой производительности общего назначения, поддержке операционной системы, кривой обучения, масштабируемости и стабильности, следует также обратить внимание назависимостиа такжеприоритет, и дляПуш сервераслужба поддержки.

7.3 Сеть доставки контента CDN

Сеть доставки контента (CDN) — это глобально распределенная сеть обратных прокси-серверов, развернутых в нескольких центрах обработки данных. Целью CDN является предоставление конечным пользователям высокодоступного и высокопроизводительного контента за счет сокращения количества обращений запросов в оба конца за счет сокращения расстояния до конечного пользователя.

Большинство основных CDN поддерживают HTTP/2, и при выборе CDN необходимо учитывать два основных фактора: поддержка push-уведомлений на стороне сервера и то, как они обрабатывают приоритет. Эти два момента оказывают значительное влияние на производительность сети в реальном мире.

8. Отладка HTTP/2

8.1 визуализация chrome devtools

Колонка «Сеть» в Chrome DevTools помогает легко и интуитивно отслеживать связь между клиентом и сервером и представляет несколько сведений в виде следующей таблицы:

  1. имя ресурса
  2. размер ресурса
  3. код состояния
  4. приоритет
  5. общее время загрузки
  6. Разбивайте время загрузки с помощью временной шкалы

Откройте колонку «Сеть» в devtools, наведите указатель мыши на ресурс Waterfall, и вы увидите подробное время каждого этапа в процессе загрузки ресурса.

  1. Connection Setup(Настройки соединения)
    1. Queueing: когда запрос задерживается механизмом рендеринга или сетевым уровнем, браузер ставит запрос в очередь в следующих случаях.
      • Существует запрос с более высоким приоритетом.
      • Этот источник открыл шесть соединений TCP, достигнув предела. Применяется только к HTTP/1.0 и HTTP/1.1.
      • Браузер временно выделяет место в кеше диска
  2. Connection Start(начать этап подключения)
    1. Stalled: запрос может бытьQueueingостановиться по любой причине, описанной в
    2. Proxy negotiation: время, необходимое браузеру для согласования запроса с прокси-сервером.
    3. DNS Lookup: время, которое потребовалось браузеру для разрешения запрошенного IP-адреса.
  3. Request/Response(ответ на запрос)
    1. Request Sent: время, которое потребовалось для отправки данных, содержащихся в запросе
    2. Waiting (TTFB): время, затраченное на ожидание начального ответа, также известное как время первого байта; это число включает время ожидания передачи ответа сервером, а также задержку между сервером и сервером.
    3. Content Download: время, которое потребовалось для получения данных для ответа
  4. Explanation(общее время)
  5. разное
    1. ServiceWorker Preparation: Браузер запускает сервис-воркер
    2. Request to ServiceWorker: Отправка запроса Service Worker
    3. Receiving Push: Браузер получает данные для этого ответа через сервер HTTP/2.
    4. Reading Push: Браузер считывает локальные данные, полученные ранее.

9. Взгляд в будущее

Одним из недостатков HTTP/2 является его зависимость от основных реализаций TCP. Как обсуждалось в разделе 3.1.3, TCP-соединения подвержены медленному запуску TCP, предотвращению перегрузки и необоснованным механизмам обработки потери пакетов. Использование одной ссылки для переноса всех запросов ресурсов, связанных со страницей, позволяет воспользоваться преимуществами мультиплексирования, однако мы по-прежнему беспомощны, когда сталкиваемся с блокировкой заголовка строки на уровне TCP. Таким образом, QUIC, разработанный Google, использует преимущества HTTP/2 и избегает этих недостатков.


Рекомендуемое чтение:

  1. Объяснение HTTP2 | Блог Wangriyu

PS: Всех приглашаю обратить внимание на мой публичный аккаунт [Front End Afternoon Tea], давайте работать вместе~

Кроме того, вы можете присоединиться к группе WeChat «Front-end Afternoon Tea Exchange Group», нажмите и удерживайте, чтобы определить QR-код ниже, чтобы добавить меня в друзья, обратите вниманиеДобавить группу, я заберу тебя в группу~