Ускоренная загрузка страниц за счет времени на размышление сервера с помощью Early Hints

Узнайте, как ваш сервер может отправлять браузеру подсказки о важных субресурсах.

Что такое ранние подсказки?

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

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

Early Hints — это код состояния HTTP ( 103 Early Hints ), используемый для отправки предварительного HTTP-ответа перед окончательным ответом. Это позволяет серверу отправлять подсказки браузеру о критических подресурсах (например, таблице стилей для страницы, критическом JavaScript) или источниках, которые, вероятно, будут использоваться страницей, пока сервер занят генерацией основного ресурса. Браузер может использовать эти подсказки для разогрева соединений и запроса дополнительных ресурсов во время ожидания основного ресурса. Другими словами, Early Hints помогает браузеру воспользоваться таким «временем на обдумывание сервера», заранее проделав некоторую работу, тем самым ускоряя загрузку страниц.

Изображение, показывающее, как Early Hints позволяет странице отправлять частичный ответ.
С ранними подсказками: сервер может предоставлять частичный ответ с подсказками по ресурсам, пока он определяет окончательный ответ.

В некоторых случаях улучшение производительности при использовании Largest Contentful Paint может достигать нескольких сотен миллисекунд, как наблюдают Shopify и Cloudflare , и до секунды быстрее, как видно из сравнения до/после:

Сравнение двух сайтов.
Сравнение ранних подсказок до и после на тестовом веб-сайте, выполненное с помощью WebPageTest (Moto G4 — DSL)

Реализация ранних подсказок

Прежде чем углубляться в тему, обратите внимание, что ранние подсказки бесполезны, если ваш сервер может сразу отправить 200 (или другие окончательные ответы). Вместо этого в таких ситуациях рассмотрите возможность использования обычной link rel=preload или link rel=preconnect в основном ответе ( HTTP-заголовок Link rel ) или в основном ответе (элементы <link> ). В случаях, когда вашему серверу требуется немного времени для генерации основного ответа, читайте дальше!

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

Теперь, когда у вас есть список приоритетных целевых страниц, следующий шаг состоит в определении того, какие источники или подресурсы будут хорошими кандидатами для подсказок предварительного подключения или предварительной загрузки в первом приближении. Как правило, это источники и подресурсы, которые в наибольшей степени влияют на ключевые пользовательские показатели, такие как «Наибольшая отрисовка контента » или «Первая отрисовка контента» . Более конкретно, ищите подресурсы, блокирующие рендеринг, такие как синхронный JavaScript, таблицы стилей или даже веб-шрифты. Аналогичным образом ищите источники, на которых размещены подресурсы, которые вносят большой вклад в ключевые показатели пользователя. Примечание. Если ваши основные ресурсы уже используют <link rel=preconnect> или <link rel=preload> , вы можете рассматривать эти источники или ресурсы среди кандидатов на ранние подсказки. Более подробную информацию можно найти в этой статье .

Второй шаг состоит в минимизации риска использования Early Hints для ресурсов или источников, которые могут быть устаревшими или больше не использоваться основным ресурсом. Например, ресурсы, которые часто обновляются и имеют версии (например, example.com/css/main.fa231e9c.css ), могут быть не лучшим выбором. Обратите внимание, что эта проблема касается не только Early Hints, она применима к любой ссылке rel=preload или rel=preconnect , где бы они ни присутствовали. Это тот тип деталей, который лучше всего решается с помощью автоматизации или шаблонизации (например, ручной процесс с большей вероятностью приведет к несовпадению хеша или URL-адресов версий между link rel=preload и фактическим тегом HTML, использующим ресурс).

В качестве примера рассмотрим следующий поток:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]

Сервер предсказывает, что понадобится main.abcd100.css , и предлагает предварительно загрузить его с помощью Early Hints:

103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]

Через несколько мгновений отображается веб-страница, включая связанный CSS. К сожалению, этот ресурс CSS часто обновляется, и основной ресурс уже на пять версий опережает прогнозируемый ресурс CSS ( abcd105 ) ( abcd100 ).

200 OK
[...]
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.abcd105.css">

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

<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">

Наконец, на стороне сервера найдите запросы основных ресурсов, отправленные браузерами, которые поддерживают Early Hints, и немедленно ответьте 103 Early Hints. В ответ 103 включите соответствующие подсказки по предварительному подключению и предварительной загрузке. Как только основной ресурс будет готов, отправьте обычный ответ (например, 200 OK в случае успеха). В целях обратной совместимости рекомендуется также включать HTTP-заголовки Link в окончательный ответ, возможно, даже дополняя их критическими ресурсами, которые стали очевидными при создании основного ресурса (например, динамическая часть ключевого ресурса, если вы следовали инструкциям " предложение разделить на две части). Вот как это будет выглядеть:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
103 Early Hints
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script

Спустя несколько мгновений:

200 OK
Content-Length: 7531
Content-Type: text/html; charset=UTF-8
Content-encoding: br
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Link: </experimental.3eab3290.css>; rel=preload; as=style
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">
   <script src="/common.js"></script>
   <link rel="preconnect" href="https://fonts.googleapis.com">

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

Хотя 103 Early Hints поддерживается во всех основных браузерах, директивы, которые можно отправлять в Early Hint, различаются в зависимости от браузера:

Поддержка предварительного подключения:

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

  • 103
  • 103
  • 120
  • 17

Поддержка предварительной загрузки:

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

  • 103
  • 103
  • 123
  • Икс

Поддержка сервера

Вот краткий обзор уровня поддержки Early Hints среди популярного программного обеспечения HTTP-сервера OSS:

Включение Early Hints: простой способ

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

Предотвращение проблем для клиентов, которые не поддерживают Early Hints

Информационные ответы HTTP в диапазоне 100 являются частью стандарта HTTP, но некоторые старые клиенты или боты могут с ними сталкиваться, поскольку до запуска 103 Early Hints они редко использовались для общего просмотра веб-страниц.

Выдача только 103 ранних подсказок в ответ на клиенты, которые отправляют заголовок HTTP-запроса sec-fetch-mode: navigate должна гарантировать, что такие подсказки отправляются только для новых клиентов, которые понимают, что нужно ждать последующего ответа. Кроме того, поскольку ранние подсказки поддерживаются только для запросов навигации (см. текущие ограничения ), это дает дополнительное преимущество, позволяющее избежать ненужной отправки их в другие запросы.

Кроме того, Early Hints рекомендуется отправлять только через соединения HTTP/2 или HTTP/3 .

Расширенный шаблон

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

Для посетителей, которые запрашивают n- ю страницу в рамках типичного пользовательского пути, вы можете адаптировать ответ Early Hints к контенту, который находится ниже и глубже на странице, другими словами, используя Early Hints на ресурсах с более низким приоритетом. Это может показаться нелогичным, учитывая, что мы рекомендовали сосредоточиться на высокоприоритетных подресурсах или источниках, блокирующих рендеринг. Однако к тому времени, как посетитель какое-то время перемещается по сайту, весьма вероятно, что в его браузере уже есть все важные ресурсы. С этого момента, возможно, имеет смысл переключить ваше внимание на ресурсы с более низким приоритетом. Например, это может означать использование Early Hints для загрузки изображений продуктов или дополнительных JS/CSS, которые необходимы только для менее частых взаимодействий с пользователем.

Текущие ограничения

Вот ограничения Early Hints, реализованные в Chrome:

  • Доступен только для запросов навигации (т. е. основной ресурс для документа верхнего уровня).
  • Поддерживается только preconnect и preload (то есть prefetch не поддерживается).
  • Ранняя подсказка, за которой следует перенаправление между источниками окончательного ответа, приведет к тому, что Chrome удалит ресурсы и соединения, полученные с помощью ранних подсказок.

Другие браузеры имеют аналогичные ограничения и дополнительно ограничивают 103 ранних подсказки только preconnect .

Что дальше?

В зависимости от интереса сообщества мы можем дополнить нашу реализацию Early Hints следующими возможностями:

  • Ранние подсказки отправляются по запросам субресурсов.
  • Ранние подсказки отправляются по запросам основных ресурсов iframe.
  • Поддержка предварительной выборки в Early Hints.

Мы приветствуем ваше мнение о том, каким аспектам следует уделять приоритетное внимание и как дальше улучшать Early Hints.

Связь с H2/Push

Если вы знакомы с устаревшей функцией HTTP2/Push , вы можете задаться вопросом, чем отличаются Early Hints. В то время как Early Hints требует, чтобы браузер начал получать критические подресурсы в обе стороны, с помощью HTTP2/Push сервер может начать отправлять подресурсы вместе с ответом. Хотя это звучит потрясающе, это привело к ключевому структурному недостатку: при использовании HTTP2/Push было чрезвычайно сложно избежать передачи подресурсов, которые уже были в браузере. Этот эффект «чрезмерного давления» привел к менее эффективному использованию пропускной способности сети, что значительно снизило выигрыш в производительности. В целом данные Chrome показали, что HTTP2/Push на самом деле негативно влияет на производительность в сети.

Напротив, Early Hints на практике работает лучше, поскольку сочетает в себе возможность отправки предварительного ответа с подсказками, которые позволяют браузеру получать или подключаться к тому, что ему действительно нужно. Хотя Early Hints не охватывает все случаи использования, которые теоретически может реализовать HTTP2/Push, мы считаем, что Early Hints — более практичное решение для ускорения навигации.

Миниатюрное изображение Пьера Бамина .