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

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

  • 102
  • 102
  • Икс
  • 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, шрифты, скрипты, изображения и сторонние ресурсы.
  • Расположение или порядок, в котором документ ссылается на ресурсы.
  • Подсказка preload ресурса, которая помогает браузеру быстрее обнаружить ресурс и загрузить его раньше.
  • Изменения приоритета вычислений для async или defer сценариев.

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

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

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

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

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

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

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

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

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

Вот несколько более сложных случаев, когда Fetch Priority может помочь вам получить необходимый вам порядок приоритета ресурсов:

  • У вас есть несколько изображений в верхней части сгиба, но не все из них должны иметь одинаковый приоритет. Например, в карусели изображений только первое видимое изображение требует более высокого приоритета.
  • Главные изображения внутри области просмотра обычно начинаются с Low или Medium приоритета. После завершения макета Chrome обнаруживает, что они находятся в области просмотра, и повышает их приоритет. Обычно это приводит к значительной задержке загрузки изображений. Предоставление приоритета выборки в разметке позволяет изображению начинаться с «высокого» приоритета и начинать загрузку намного раньше.

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

Атрибут 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" (◉) в каждой строке обозначает приоритет по умолчанию для этого типа ресурса.

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

fetchpriority устанавливает относительный приоритет , то есть повышает или понижает приоритет по умолчанию на соответствующую величину, вместо того, чтобы явно устанавливать приоритет на High или Low . Это часто приводит к High или Low приоритету, но не всегда. Например, критический CSS с fetchpriority="high" сохраняет приоритет "VeryHigh"/"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>

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

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

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

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

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

<!-- Preload CSS without blocking 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>

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

Браузер выполняет 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 с низкой пропускной способностью. В этих случаях расстановка приоритетов может помочь устранить узкие места.

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

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

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

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

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

История

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