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

Когда вы открываете веб-страницу, браузер запрашивает HTML-документ у сервера, анализирует его содержимое и отправляет отдельные запросы на все необходимые ресурсы. Как разработчик, вы уже знаете обо всех ресурсах, необходимых вашей странице, и о том, какие из них наиболее важны. Вы можете использовать эти знания, чтобы заранее запросить критически важные ресурсы и ускорить процесс загрузки. В этой статье объясняется, как этого добиться с помощью <link rel="preload"> .

Как работает предварительная загрузка

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

Скриншот панели «Сеть» в инструментах разработчика Chrome.
В этом примере шрифт Pacifico определен в таблице стилей с помощью правила @font-face . Браузер загружает файл шрифта только после завершения загрузки и анализа таблицы стилей.

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

Скриншот панели «Сеть» в инструментах разработчика Chrome после предварительной загрузки.
В этом примере шрифт Pacifico загружен предварительно, поэтому загрузка происходит параллельно с загрузкой таблицы стилей.

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

Аудит запросов на предварительную загрузку ключей в Lighthouse.

Для предварительной загрузки ресурсов добавьте в заголовок HTML-документа тег <link> с rel="preload" :

<link rel="preload" as="script" href="critical.js">

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

Указания на доступ к ресурсам, например, preconnect и prefetch , выполняются по усмотрению браузера. preload , с другой стороны, является обязательной для браузера. Современные браузеры и так неплохо справляются с расстановкой приоритетов ресурсов, поэтому важно использовать preload экономно и загружать только наиболее важные ресурсы.

Неиспользуемые предварительно загруженные файлы вызывают предупреждение в консоли Chrome примерно через 3 секунды после события load .

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

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

Предварительная загрузка ресурсов, определенных в CSS.

Шрифты, определенные с помощью правил @font-face , или фоновые изображения, определенные в CSS-файлах, не обнаруживаются до тех пор, пока браузер не загрузит и не проанализирует эти CSS-файлы. Предварительная загрузка этих ресурсов гарантирует, что они будут загружены до того, как будут загружены CSS-файлы.

Предварительная загрузка CSS-файлов

Если вы используете подход с критическим CSS , вы разделяете свой CSS на две части. Критический CSS, необходимый для отображения контента, видимого без прокрутки, встраивается в раздел <head> документа, а некритический CSS обычно загружается с помощью JavaScript. Ожидание выполнения JavaScript перед загрузкой некритического CSS может вызвать задержки в отображении при прокрутке страницы, поэтому рекомендуется использовать <link rel="preload"> для более быстрой загрузки.

Предварительная загрузка файлов JavaScript

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

Как реализовать rel=preload

Простейший способ реализовать preload — добавить тег <link> в раздел <head> документа:

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

Указание атрибута as помогает браузеру установить приоритет предварительно загруженного ресурса в соответствии с его типом, задать правильные заголовки и определить, существует ли ресурс уже в кэше. Допустимые значения для этого атрибута включают: script , style , font , image и другие .

Некоторые типы ресурсов, например шрифты, загружаются в анонимном режиме . Для них необходимо установить атрибут crossorigin с помощью preload :

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

Элементы <link> также принимают атрибут type , который содержит MIME-тип связанного ресурса. Браузеры используют значение атрибута type , чтобы гарантировать предварительную загрузку ресурсов только в том случае, если их тип файла поддерживается. Если браузер не поддерживает указанный тип ресурса, он проигнорирует <link rel="preload"> .

Также можно предварительно загрузить любой тип ресурса с помощью HTTP-заголовка Link :

Link: </css/style.css>; rel="preload"; as="style"

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

Предварительная загрузка модулей JavaScript с помощью webpack

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

import(_/* webpackPreload: true */_ "CriticalChunk")

Если вы используете более старую версию webpack, воспользуйтесь сторонним плагином, например preload-webpack-plugin .

Влияние предварительной загрузки на основные показатели веб-инфраструктуры.

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

Largest Contentful Paint (LCP)

Предварительная загрузка оказывает существенное влияние на показатель Largest Contentful Paint (LCP) в отношении шрифтов и изображений, поскольку как изображения, так и текстовые узлы могут быть кандидатами на включение в LCP . Изображения-заголовки и большие блоки текста, отображаемые с использованием веб-шрифтов, могут значительно выиграть от грамотно размещенной подсказки предварительной загрузки, и их следует использовать, когда есть возможность быстрее доставить пользователю эти важные элементы контента.

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

Вместо этого сосредоточьтесь на нескольких ценных ресурсах, которые, как вы знаете, выиграют от грамотной предварительной загрузки. При предварительной загрузке шрифтов убедитесь, что вы используете шрифты в формате WOFF 2.0, чтобы максимально сократить время загрузки ресурсов. Поскольку WOFF 2.0 отлично поддерживается браузерами , использование более старых форматов, таких как WOFF 1.0 или TrueType (TTF), задержит загрузку LCP, если кандидатом на LCP является текстовый узел.

Что касается LCP и JavaScript, вам необходимо убедиться, что вы отправляете полную разметку с сервера, чтобы сканер предварительной загрузки браузера работал корректно. Если вы предоставляете пользовательский опыт, который полностью полагается на JavaScript для рендеринга разметки и не может отправлять HTML-код, генерируемый сервером, было бы выгодно вмешаться там, где сканер предварительной загрузки браузера не может, и предварительно загрузить ресурсы, которые в противном случае стали бы доступны только после завершения загрузки и выполнения JavaScript.

Накопительное изменение компоновки (CLS)

Совокупное смещение макета (CLS) — особенно важный показатель, когда речь идёт о веб-шрифтах, и CLS существенно взаимодействует с веб-шрифтами, использующими свойство CSS font-display для управления загрузкой шрифтов. Чтобы минимизировать смещения макета, связанные с веб-шрифтами, рассмотрите следующие стратегии:

  1. Предварительная загрузка шрифтов с использованием значения по умолчанию block для font-display — это тонкий баланс. Блокировка отображения шрифтов без резервного варианта может рассматриваться как проблема пользовательского опыта. С одной стороны, загрузка шрифтов с помощью font-display: block; исключает смещения макета, связанные со шрифтами в веб-страницах. С другой стороны, вам все равно нужно, чтобы эти веб-шрифты загружались как можно быстрее, если они имеют решающее значение для пользовательского опыта. Сочетание предварительной загрузки с font-display: block; может быть приемлемым компромиссом.
  2. Предварительная загрузка шрифтов с использованием fallback значения для font-display . fallback представляет собой компромисс между swap и block , поскольку имеет чрезвычайно короткий период блокировки.
  3. Используйте optional значение для font-display без предварительной загрузки. Если веб-шрифт не является критически важным для пользовательского опыта, но все же используется для отображения значительного объема текста на странице, рассмотрите возможность использования optional значения. В неблагоприятных условиях optional будет отображать текст страницы резервным шрифтом, пока шрифт загружается в фоновом режиме для следующей навигации. В результате в этих условиях улучшается CLS, поскольку системные шрифты будут отображаться немедленно, а последующие загрузки страниц будут загружать шрифт немедленно без изменений макета.

Показатель CLS (количество символов в секунду) сложно оптимизировать применительно к веб-шрифтам. Как всегда, экспериментируйте в лабораторных условиях , но доверяйте данным, полученным в реальных условиях , чтобы определить, улучшают ли ваши стратегии загрузки шрифтов показатель CLS или ухудшают его.

Взаимодействие с Next Paint (INP)

Показатель «Взаимодействие до следующей отрисовки» (Interaction to Next Paint, INP) измеряет скорость реакции на действия пользователя. Поскольку большая часть интерактивности в интернете обеспечивается JavaScript, предварительная загрузка JavaScript, отвечающего за важные взаимодействия, может помочь снизить INP страницы. Однако следует помнить, что предварительная загрузка слишком большого количества JavaScript при запуске может привести к непредвиденным негативным последствиям, если слишком много ресурсов будут конкурировать за пропускную способность.

Также следует внимательно отнестись к разделению кода . Разделение кода — это отличная оптимизация для уменьшения объема загружаемого JavaScript при запуске, но взаимодействие может задерживаться, если оно зависит от JavaScript, загружаемого в самом начале взаимодействия. Чтобы компенсировать это, вам нужно будет изучить намерения пользователя и внедрить предварительную загрузку необходимых фрагментов JavaScript до начала взаимодействия. Например, можно предварительно загрузить JavaScript, необходимый для проверки содержимого формы, когда любое из полей формы находится в фокусе.

Заключение

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