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

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

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

Как использовать ранние подсказки
Первый шаг к использованию Early Hints состоит в определении главных целевых страниц, то есть страниц, с которых обычно начинают пользователи, посещая ваш сайт. Это может быть домашняя страница или популярные страницы со списком продуктов, если у вас много пользователей, заходящих с других сайтов. Причина, по которой эти точки входа важнее других страниц, заключается в том, что полезность Early Hints уменьшается по мере того, как пользователь перемещается по вашему сайту (то есть браузер, скорее всего, будет иметь все необходимые ему подресурсы при втором или третьем последующем переходе). Также всегда полезно произвести хорошее первое впечатление!
Теперь, когда у вас есть этот приоритетный список целевых страниц, следующим шагом будет определение того, какие источники или подресурсы будут хорошими кандидатами для подсказок preconnect
или preload
. Как правило, это источники и подресурсы, которые вносят наибольший вклад в ключевые показатели пользователя, такие как Largest Contentful Paint или First Contentful Paint . Более конкретно, ищите подресурсы, блокирующие рендеринг, такие как синхронный JavaScript, таблицы стилей или даже веб-шрифты. Аналогично, ищите источники, которые размещают подресурсы, которые вносят большой вклад в ключевые показатели пользователя.
Также обратите внимание, что если ваши основные ресурсы уже используют preconnect
или preload
, вы можете рассмотреть эти источники или ресурсы среди кандидатов для Early Hints. Подробнее см. в статье «Как оптимизировать LCP» . Однако наивное копирование директив preconnect
и preload
из HTML в Early Hints может оказаться неоптимальным .
При использовании их в HTML обычно требуется preconnect
или preload
ресурсы, которые сканер предварительной загрузки не обнаружит в HTML, например, шрифты или фоновые изображения, которые в противном случае были бы обнаружены поздно. Для Early Hints у вас не будет HTML, поэтому вместо этого вы можете захотеть preconnect
к критически важным доменам или preload
критические ресурсы, которые в противном случае были бы обнаружены рано в HTML, например, предварительно загрузить main.css
или app.js
Кроме того, не все браузеры поддерживают preload
для Early Hints — см. Поддержка браузеров .
Второй шаг заключается в минимизации риска использования Early Hints для ресурсов или источников, которые могут быть устаревшими или больше не использоваться основным ресурсом. Например, ресурсы, которые часто обновляются и версионируются (например, example.com/css/main.fa231e9c.css
), могут быть не лучшим выбором. Обратите внимание, что эта проблема не относится только к Early Hints, она относится к любой preload
или preconnect
, где бы они ни присутствовали. Это тот тип деталей, который лучше всего решать с помощью автоматизации или шаблонизации (например, ручной процесс с большей вероятностью приведет к несовпадению хэш-адресов или URL-адресов версии между 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 часто обновляется, и основной ресурс уже опережает на пять версий ( abcd105
) прогнозируемый ресурс CSS ( 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 включите соответствующие preconnect и preload hints. Как только основной ресурс будет готов, отправьте обычный ответ (например, 200 OK в случае успеха). Для обратной совместимости хорошей практикой будет также включать заголовки Link
HTTP в окончательный ответ, возможно, даже дополняя его критическими ресурсами, которые стали очевидны в ходе генерации основного ресурса (например, динамическая часть ключевого ресурса, если вы последовали совету «разделить на две части»). Вот как это будет выглядеть:
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, различаются в зависимости от браузера:
Поддержка предварительного подключения:
Browser Support
Поддержка предварительной загрузки:
Browser Support
Chrome DevTools также поддерживает 103 Early Hints , а заголовки Link
можно увидеть в ресурсах документа:

Link
Early Hints отображаются в Chrome DevTools. Обратите внимание, чтобы использовать ресурсы Early Hints, не следует отмечать Disable cache
в DevTools, поскольку Early Hints использует кэш браузера. Для предварительно загруженных ресурсов инициатор будет отображаться как early-hints
, а размер как (Disk cache)
:

early-hints
и загружаются из кэша диска.Для тестирования HTTPS также требуется доверенный сертификат.
Firefox (начиная с версии 126) не имеет явной поддержки 103 Early Hints в DevTools, но ресурсы, загруженные с использованием Early Hints, не отображают информацию заголовка HTTP, что является одним из показателей того, что они были загружены с использованием Early Hints.
Поддержка сервера
Ниже приведен краткий обзор уровня поддержки Early Hints среди популярного программного обеспечения HTTP-серверов с открытым исходным кодом:
- Apache: поддерживается с использованием mod_http2.
- H2O: поддерживается .
- NGINX: поддерживается .
- Узел: поддерживается с версии 18.11.0 для http и http2
Включить ранние подсказки — более простой способ
Если вы используете одну из следующих CDN или платформ, вам может не потребоваться вручную внедрять Early Hints. Обратитесь к онлайн-документации вашего поставщика решений, чтобы узнать, поддерживает ли он Early Hints, или обратитесь к неисчерпывающему списку здесь:
Как избежать проблем для клиентов, которые не поддерживают Early Hints
Информационные HTTP-ответы в диапазоне 100 являются частью стандарта HTTP, но некоторые старые клиенты или боты могут испытывать с ними трудности, поскольку до запуска 103 Early Hints они редко использовались для обычного просмотра веб-страниц.
Только отправка 103 Early Hints в ответ на запросы клиентов, отправляющих 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 откажется от ресурсов и подключений, полученных с помощью ранних подсказок.
- Ресурсы, предварительно загруженные с помощью Early Hints, хранятся в HTTP-кэше и извлекаются оттуда страницей позже. Поэтому только кэшируемые ресурсы могут быть предварительно загружены с помощью Early Hints, иначе ресурс будет дважды извлечен (один раз Early Hints и еще раз документом). В Chrome HTTP-кэш отключен для недоверенных сертификатов HTTPS (даже если вы продолжите загрузку страницы).
- Предварительная загрузка адаптивных изображений (с использованием
imagesrcset
,imagesizes
илиmedia
) не поддерживается с использованием заголовков HTTP<link>
, поскольку область просмотра не определена до создания документа. Это означает, что 103 Early hints не могут использоваться для предварительной загрузки адаптивных изображений и могут загружать неправильное изображение при использовании для этого. Следите за этим обсуждением предложений о том, как лучше с этим справиться .
Другие браузеры имеют схожие ограничения и, как отмечалось ранее , некоторые еще больше ограничивают 103 ранних подсказки только preconnect
.
Что дальше?
В зависимости от интереса сообщества мы можем расширить реализацию Early Hints следующими возможностями:
- Ранние подсказки для некэшируемых ресурсов, использующих кеш памяти, а не кеш HTTP.
- Ранние подсказки отправлены по запросам подресурсов.
- Ранние подсказки отправлены по основным запросам ресурсов 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 является более практичным решением для ускорения навигации.
Миниатюрное изображение Пьера Бамина .