Оптимизируйте загрузку ресурсов с помощью API Fetch Priority.

API-интерфейс Fetch Priority указывает относительный приоритет ресурсов для браузера. Это может обеспечить оптимальную загрузку и улучшить основные веб-показатели.

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

  • Хром: 102.
  • Край: 102.
  • Firefox: за флагом.
  • Сафари: 17.2.

Источник

Когда браузер анализирует веб-страницу и начинает обнаруживать и загружать ресурсы, такие как изображения, сценарии или CSS, он назначает им priority выборки, чтобы можно было загрузить их в оптимальном порядке. Приоритет ресурса обычно зависит от того, что это такое и где он находится в документе. Например, изображения в области просмотра могут иметь High приоритет, а приоритет для ранее загруженных CSS, блокирующих рендеринг с использованием <link> в <head> может быть Very High . Браузеры довольно хорошо распределяют приоритеты, которые работают хорошо, но не во всех случаях могут быть оптимальными.

На этой странице обсуждается API-интерфейс Fetch Priority и HTML-атрибут fetchpriority , который позволяет указать относительный приоритет ресурса ( high или low ). Приоритет выборки может помочь оптимизировать основные веб-показатели.

Краткое содержание

Несколько ключевых областей, в которых может помочь функция Fetch Priority:

  • Повышение приоритета изображения LCP путем указания fetchpriority="high" в элементе изображения, что приводит к более быстрому выполнению LCP.
  • Повышение приоритета async скриптов с использованием лучшей семантики, чем наиболее распространенный в настоящее время хак (вставка <link rel="preload"> для async скрипта).
  • Уменьшен приоритет скриптов позднего тела, чтобы обеспечить лучшую последовательность изображений.
Диафильм, сравнивающий два теста главной страницы Google Flights. Внизу Fetch Priority используется для повышения приоритета главного изображения, что приводит к уменьшению LCP на 0,7 секунды.
Приоритет выборки улучшает самую большую отрисовку контента с 2,6 до 1,9 с в тесте Google Flights.

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

Приоритет выборки дополняет эти подсказки по ресурсам . Это сигнал на основе разметки, доступный через атрибут fetchpriority , который разработчики могут использовать для указания относительного приоритета определенного ресурса. Вы также можете использовать эти подсказки через JavaScript и Fetch API со свойством priority , чтобы влиять на приоритет выборки ресурсов, выполняемых для данных. Приоритет выборки также может дополнять предварительную загрузку. Возьмите самое большое содержательное изображение Paint, которое при предварительной загрузке все равно будет иметь низкий приоритет. Если его оттесняют другие ранние ресурсы с низким приоритетом, использование приоритета выборки может помочь ускорить загрузку изображения.

Приоритет ресурса

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

  • Тип ресурса, например CSS, шрифты, скрипты, изображения и сторонние ресурсы.
  • Расположение или порядок, в котором документ ссылается на ресурсы.
  • Используются ли в сценариях атрибуты async или defer .

В следующей таблице показано, как Chrome расставляет приоритеты и упорядочивает большинство ресурсов:

Загрузка на этапе блокировки макета Загружайте по одному на этапе блокировки макета.
Мигать
Приоритет
ОченьВысокая Высокий Середина Низкий Очень Низкий
Инструменты разработчика
Приоритет
Самый высокий Высокий Середина Низкий Самый низкий
Основной ресурс
CSS (ранний**) CSS (поздно**) CSS (несоответствие медиа***)
Скрипт (ранний** или нет из сканера предварительной загрузки) Сценарий (поздно**) Скрипт (асинхронный)
Шрифт Шрифт (rel=предварительная загрузка)
Импорт
Изображение (в окне просмотра) Изображение (первые 5 изображений > 10 000 пикселей2) Изображение
Медиа (видео/аудио)
Предварительная выборка
XSL
XHR (синхронизация) XHR/выборка* (асинхронный)

Браузер загружает ресурсы с одинаковым вычисленным приоритетом в том порядке, в котором они были обнаружены. Вы можете проверить приоритет, назначенный различным ресурсам, при загрузке страницы на вкладке « Сеть инструментов разработчика Chrome». (Убедитесь, что вы включили столбец приоритета , щелкнув правой кнопкой мыши заголовок таблицы и отметив его галочкой).

Вкладка «Сеть» инструментов разработчика Chrome, на которой перечислен ряд ресурсов шрифтов. Все они имеют высший приоритет.
Приоритет для type = "font" на странице сведений о новостях BBC
Вкладка «Сеть» инструментов разработчика Chrome, на которой перечислен ряд ресурсов шрифтов. Они представляют собой смесь низкого и высокого приоритета.
Приоритет для type = "script" на странице сведений о новостях BBC.

При изменении приоритетов вы можете увидеть начальный и конечный приоритет в настройке «Большие строки запроса» или во всплывающей подсказке.

Вкладка «Сеть» в DevTools Chrome. Параметр «Большие строки запроса» отмечен галочкой, а в столбце «Приоритет» отображается первое изображение с высоким приоритетом и другим начальным приоритетом — средним ниже. То же самое показано во всплывающей подсказке.
Приоритетные изменения в DevTools.

Когда вам может понадобиться приоритет выборки?

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

  • Размещайте теги ресурсов, такие как <script> и <link> в том порядке, в котором вы хотите, чтобы браузер их загружал. Ресурсы с одинаковым приоритетом обычно загружаются в порядке их обнаружения.
  • Используйте подсказку preload ресурса , чтобы загрузить необходимые ресурсы раньше, особенно для ресурсов, которые браузеру нелегко обнаружить на ранней стадии.
  • Используйте async или defer загрузку скриптов, не блокируя другие ресурсы.
  • Лениво загружайте содержимое нижней части страницы, чтобы браузер мог использовать доступную пропускную способность для более важных ресурсов верхней части страницы.

Эти методы помогают контролировать вычисления приоритетов браузера, тем самым повышая производительность и основные веб-показатели . Например, когда критическое фоновое изображение предварительно загружено, его можно обнаружить гораздо раньше, что улучшает функцию Largest Contentful Paint ( LCP ).

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

  • У вас есть несколько изображений в верхней части сгиба, но не все из них должны иметь одинаковый приоритет. Например, в карусели изображений только первое видимое изображение требует более высокого приоритета, а остальные, обычно изначально за кадром, могут иметь более низкий приоритет.
  • Изображения внутри области просмотра обычно начинаются с Low приоритета. После завершения макета Chrome обнаруживает, что они находятся в области просмотра, и повышает их приоритет. Обычно это приводит к значительной задержке загрузки критически важных изображений, например главных изображений. Предоставление приоритета выборки в разметке позволяет изображению начинаться с High приоритетом и начинать загрузку намного раньше. В попытке несколько автоматизировать это, первым пяти более крупным изображениям Chrome присваивает Medium приоритет, что помогает, но явный fetchpriority="high" будет еще лучше.

    Предварительная загрузка по-прежнему требуется для раннего обнаружения изображений LCP, включенных в качестве фона CSS. Чтобы повысить приоритет фоновых изображений, включите fetchpriority='high' в предварительную загрузку.
  • Объявление сценариев как async или defer указывает браузеру загружать их асинхронно. Однако, как показано в таблице приоритетов , этим сценариям также присвоен «Низкий» приоритет. Возможно, вы захотите повысить их приоритет, обеспечив при этом асинхронную загрузку, особенно для сценариев, критически важных для взаимодействия с пользователем.
  • Если вы используете API JavaScript fetch() для асинхронной выборки ресурсов или данных, браузер назначает ему High приоритет. Возможно, вам захочется, чтобы некоторые из ваших выборок выполнялись с более низким приоритетом, особенно если вы смешиваете фоновые вызовы API с вызовами API, которые отвечают на ввод пользователя. Отметьте фоновые вызовы API как Low приоритет, а интерактивные вызовы API — как High приоритет.
  • Браузер назначает CSS и шрифтам High приоритет, но некоторые из этих ресурсов могут быть более важными, чем другие. Вы можете использовать приоритет выборки, чтобы снизить приоритет некритических ресурсов (обратите внимание, что ранний CSS блокирует рендеринг, поэтому обычно должен иметь High приоритет).

Атрибут fetchpriority

Используйте HTML-атрибут fetchpriority , чтобы указать приоритет загрузки для таких типов ресурсов, как CSS, шрифты, сценарии и изображения, при загрузке с использованием тегов link , img или script . Он может принимать следующие значения:

  • high : ресурс имеет более высокий приоритет, и вы хотите, чтобы браузер установил для него более высокий приоритет, чем обычно, если собственная эвристика браузера не препятствует этому.
  • low : ресурс имеет более низкий приоритет, и вы хотите, чтобы браузер лишил его приоритета, опять же, если это позволяет его эвристика.
  • auto : значение по умолчанию, которое позволяет браузеру выбирать соответствующий приоритет.

Вот несколько примеров использования атрибута fetchpriority в разметке, а также свойства priority , эквивалентного сценарию.

<!-- We don't want a high priority for this above-the-fold image -->
<img src="/images/in_viewport_but_not_important.svg" fetchpriority="low" alt="I'm an unimportant image!">

<!-- We want to initiate an early fetch for a resource, but also deprioritize it -->
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low">

<script>
  fetch('https://example.com/', {priority: 'low'})
  .then(data => {
    // Trigger a low priority fetch
  });
</script>

Эффекты приоритета браузера и fetchpriority

Вы можете применить атрибут fetchpriority к различным ресурсам, как показано в следующей таблице, чтобы увеличить или уменьшить их вычисляемый приоритет. fetchpriority="auto" (◉) в каждой строке обозначает приоритет по умолчанию для этого типа ресурса. (также доступен в виде Google Doc ).

Загрузка на этапе блокировки макета Загружайте по одному на этапе блокировки макета.
Мигать
Приоритет
ОченьВысокая Высокий Середина Низкий Очень Низкий
Инструменты разработчика
Приоритет
Самый высокий Высокий Середина Низкий Самый низкий
Основной ресурс
CSS (ранний**) ⬆◉
CSS (поздно**)
CSS (несоответствие медиа***) ⬆*** ◉⬇
Скрипт (ранний** или нет из сканера предварительной загрузки) ⬆◉
Сценарий (поздно**)
Скрипт (асинхронный/отложенный) ◉⬇
Шрифт
Шрифт (rel=предварительная загрузка) ⬆◉
Импорт
Изображение (во вьюпорте – после макета) ⬆◉
Изображение (первые 5 изображений > 10 000 пикселей2)
Изображение ◉⬇
Медиа (видео/аудио)
XHR (синхронизация) – устаревший.
XHR/выборка* (асинхронный) ⬆◉
Предварительная выборка
XSL

fetchpriority устанавливает относительный приоритет , то есть повышает или понижает приоритет по умолчанию на соответствующую величину, вместо того, чтобы явно устанавливать приоритет на High или Low . Это часто приводит к High или Low приоритету, но не всегда. Например, критический CSS с fetchpriority="high" сохраняет приоритет "Very High"/"Highest", а использование fetchpriority="low" для этих элементов сохраняет приоритет "High". Ни в одном из этих случаев не требуется явная установка приоритета High или Low .

Варианты использования

Используйте атрибут fetchpriority , если хотите дать браузеру дополнительную подсказку о том, с каким приоритетом следует получать ресурс.

Увеличьте приоритет изображения LCP.

Вы можете указать fetchpriority="high" чтобы повысить приоритет LCP или других важных изображений.

<img src="lcp-image.jpg" fetchpriority="high">

Следующее сравнение показывает страницу Google Flights с фоновым изображением LCP, загруженным с приоритетом выборки и без него. При установке высокого приоритета время LCP улучшилось с 2,6 до 1,9 с .

Эксперимент проводился с использованием работников Cloudflare для переписывания страницы Google Flights с использованием приоритета выборки.

Используйте fetchpriority="low" чтобы понизить приоритет изображений в верхней части экрана, которые не являются важными в данный момент, например закадровые изображения в карусели изображений.

<ul class="carousel">
  <img src="img/carousel-1.jpg" fetchpriority="high">
  <img src="img/carousel-2.jpg" fetchpriority="low">
  <img src="img/carousel-3.jpg" fetchpriority="low">
  <img src="img/carousel-4.jpg" fetchpriority="low">
</ul>

Хотя изображения 2–4 будут находиться за пределами области просмотра, их можно считать «достаточно близкими», чтобы поднять их до high , а также загрузить, даже если добавлен атрибут load=lazy . Поэтому fetchpriority="low" является правильным решением.

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

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

Понизить приоритет предварительно загруженных ресурсов

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

<!-- Lower priority only for non-critical preloaded scripts -->
<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" as="script" href="non-critical-script.js" fetchpriority="low">

<!-- Preload CSS without blocking render, or other resources -->
<link rel="preload" as="style" href="theme.css" fetchpriority="low" onload="this.rel='stylesheet'">

Изменение приоритетов сценариев

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

<script src="async_but_important.js" async fetchpriority="high"></script>

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

<script src="blocking_but_unimportant.js" fetchpriority="low"></script>

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

Альтернативой, если необходим завершенный DOM, является использование атрибута defer (который выполняется по порядку после DOMContentLoaded ) или даже async внизу страницы.

Понизьте приоритет для выборки некритических данных.

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

// Important validation data (high by default)
let authenticate = await fetch('/user');

// Less important content data (suggested low)
let suggestedContent = await fetch('/content/suggested', {priority: 'low'});

Замечания по реализации Fetch Priority

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

  • Атрибут fetchpriority — это подсказка, а не директива. Браузер пытается уважать предпочтения разработчика, но он также может применять свои предпочтения приоритета ресурсов для разрешения конфликтов.
  • Не путайте приоритет выборки с предварительной загрузкой:

    • Предварительная загрузка — это обязательная выборка, а не подсказка.
    • Предварительная загрузка позволяет браузеру обнаружить ресурс раньше, но он по-прежнему выбирает ресурс с приоритетом по умолчанию. И наоборот, приоритет выборки не помогает улучшить обнаруживаемость, но позволяет увеличивать или уменьшать приоритет выборки.
    • Часто легче наблюдать и измерять эффект предварительной нагрузки, чем эффект изменения приоритета.

    Fetch Priority может дополнять предварительную загрузку, увеличивая степень детализации приоритезации. Если вы уже указали предварительную загрузку в качестве одного из первых элементов в <head> для изображения LCP, то high приоритет выборки может не существенно улучшить LCP. Однако если предварительная загрузка происходит после загрузки других ресурсов, high приоритет выборки может еще больше улучшить LCP. Если критическое изображение является фоновым изображением CSS, предварительно загрузите его с помощью fetchpriority = "high" .

  • Улучшение времени загрузки за счет определения приоритетов более актуально в средах, где больше ресурсов конкурируют за доступную пропускную способность сети. Это характерно для соединений HTTP/1.x, где параллельная загрузка невозможна, или для соединений HTTP/2 или HTTP/3 с низкой пропускной способностью. В этих случаях расстановка приоритетов может помочь устранить узкие места.

  • CDN не реализуют приоритезацию HTTP/2 неравномерно, как и HTTP/3. Даже если браузер передает приоритет из Fetch Priority, CDN может не изменить приоритет ресурсов в указанном порядке. Это затрудняет тестирование приоритета выборки. Приоритеты применяются как внутри браузера, так и с помощью протоколов, поддерживающих определение приоритетов (HTTP/2 и HTTP/3). По-прежнему стоит использовать Fetch Priority только для внутренней приоритезации браузера, независимо от поддержки CDN или источника, поскольку приоритеты часто меняются, когда браузер запрашивает ресурсы. Например, ресурсы с низким приоритетом, такие как изображения, часто не запрашиваются, пока браузер обрабатывает критические элементы <head> .

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

Разработчикам следует использовать предварительную загрузку по прямому назначению — для предварительной загрузки ресурсов, не обнаруживаемых парсером (шрифты, импорт, фоновые изображения LCP). Размещение подсказки preload будет влиять на то, когда ресурс будет предварительно загружен.

Приоритет выборки определяет, как ресурс должен быть получен при его получении.

Советы по использованию предварительных загрузок

При использовании предварительных загрузок помните следующее:

  • Включение предварительной загрузки в заголовки HTTP ставит ее перед всем остальным в порядке загрузки.
  • Как правило, предварительные загрузки загружаются в том порядке, в котором анализатор получает их для чего-либо со Medium приоритетом или выше. Будьте осторожны, если вы включаете предварительную загрузку в начало HTML.
  • Предварительная загрузка шрифта, вероятно, лучше всего работает в конце заголовка или начале тела.
  • Предварительные загрузки импорта (динамический import() или modulepreload ) должны выполняться после тега скрипта, который требует импорта, поэтому убедитесь, что скрипт загружается или анализируется первым, чтобы его можно было оценить во время загрузки его зависимостей.
  • Предварительная загрузка изображений по умолчанию имеет Low или Medium приоритет. Упорядочивайте их относительно асинхронных сценариев и других тегов с низким или наименьшим приоритетом.

История

Впервые с приоритетом выборки экспериментировали в Chrome в качестве пробной версии источника в 2018 году, а затем снова в 2021 году с использованием атрибута importance . В то время это называлось Priority Hints . С тех пор интерфейс изменился на fetchpriority для HTML и priority для Fetch API JavaScript в рамках процесса веб-стандартов. Чтобы избежать путаницы, мы теперь называем это приоритетом выборки API.

Заключение

Разработчиков, вероятно, заинтересует Fetch Priority с исправлениями в поведении предварительной загрузки и недавним акцентом на Core Web Vitals и LCP. Теперь у них есть дополнительные ручки для достижения предпочтительной последовательности загрузки.