Когда вы открываете веб-страницу, браузер запрашивает HTML-документ с сервера, анализирует его содержимое и отправляет отдельные запросы для любых ссылочных ресурсов. Как разработчик, вы уже знаете обо всех ресурсах, которые нужны вашей странице, и какие из них наиболее важны. Вы можете использовать эти знания, чтобы заранее запросить критически важные ресурсы и ускорить процесс загрузки. В этом посте объясняется, как добиться этого с помощью <link rel="preload">
.
Как работает предварительная загрузка
Предварительная загрузка лучше всего подходит для ресурсов, которые обычно обнаруживаются браузером поздно.
Предварительно загружая определенный ресурс, вы сообщаете браузеру, что хотели бы получить его раньше, чем в противном случае браузер обнаружил бы его, поскольку вы уверены, что он важен для текущей страницы.
Цепочка критических запросов представляет собой порядок ресурсов, которым присвоен приоритет и которые извлекаются браузером. Lighthouse идентифицирует активы, находящиеся на третьем уровне этой цепочки, как поздно обнаруженные. Вы можете использовать аудит запросов ключей предварительной загрузки, чтобы определить, какие ресурсы следует загрузить предварительно.
Вы можете предварительно загрузить ресурсы, добавив тег <link>
с rel="preload"
в заголовок вашего HTML-документа:
<link rel="preload" as="script" href="critical.js">
Браузер кэширует предварительно загруженные ресурсы, поэтому они доступны немедленно, когда это необходимо. (Он не выполняет сценарии и не применяет таблицы стилей.)
Подсказки ресурсов, например preconnect
и prefetch
, выполняются по усмотрению браузера. С другой стороны, preload
обязательна для браузера. Современные браузеры уже довольно хорошо расставляют приоритеты ресурсов, поэтому важно экономно использовать preload
и предварительно загружать только наиболее важные ресурсы.
Неиспользованные предварительные загрузки вызывают предупреждение консоли в Chrome примерно через 3 секунды после события load
.
Варианты использования
Предварительная загрузка ресурсов, определенных в 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 с помощью веб-пакета
Если вы используете сборщик модулей, который создает файлы сборки вашего приложения, вам необходимо проверить, поддерживает ли он внедрение тегов предварительной загрузки. В веб-пакете версии 4.6.0 или новее предварительная загрузка поддерживается за счет использования магических комментариев внутри import()
:
import(_/* webpackPreload: true */_ "CriticalChunk")
Если вы используете более старую версию веб-пакета, используйте сторонний плагин, например preload-webpack-plugin .
Влияние предварительной загрузки на основные веб-показатели
Предварительная загрузка — это мощная оптимизация производительности, влияющая на скорость загрузки. Такая оптимизация может привести к изменениям в основных веб-показателях вашего сайта, и важно об этом знать.
Самая большая содержательная краска (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
для управления загрузкой шрифтов. Чтобы свести к минимуму изменения макета, связанные с веб-шрифтами, рассмотрите следующие стратегии:
- Предварительно загрузите шрифты, используя значение
block
по умолчанию дляfont-display
. Это тонкий баланс. Блокировку отображения шрифтов без резервного варианта можно считать проблемой взаимодействия с пользователем. С одной стороны, загрузка шрифтов с помощьюfont-display: block;
устраняет сдвиги макета, связанные с веб-шрифтами. С другой стороны, вы все равно хотите загрузить эти веб-шрифты как можно скорее, если они имеют решающее значение для взаимодействия с пользователем. Объединение предварительной загрузки сfont-display: block;
может быть приемлемым компромиссом. - Предварительно загрузите шрифты, используя
fallback
значение дляfont-display
.fallback
— это компромисс междуswap
иblock
, поскольку он имеет чрезвычайно короткий период блокировки. - Используйте
optional
значение дляfont-display
без предварительной загрузки. Если веб-шрифт не имеет решающего значения для взаимодействия с пользователем, но он по-прежнему используется для отображения значительного объема текста на странице, рассмотрите возможность использованияoptional
значения. В неблагоприятных условияхoptional
будет отображаться текст страницы резервным шрифтом, пока шрифт загружается в фоновом режиме для следующей навигации. Конечным результатом в этих условиях является улучшение CLS, поскольку системные шрифты будут отображаться немедленно, а при последующих загрузках страниц шрифт будет загружаться немедленно без изменений макета.
CLS — это сложный показатель для оптимизации, когда дело касается веб-шрифтов. Как всегда, экспериментируйте в лаборатории , но доверьтесь своим полевым данным , чтобы определить, улучшают ли ваши стратегии загрузки шрифтов CLS или ухудшают его.
Взаимодействие со следующей отрисовкой (INP)
Взаимодействие с Next Paint — это показатель, который измеряет реакцию на ввод пользователя. Поскольку львиная доля интерактивности в сети обеспечивается JavaScript, предварительная загрузка JavaScript, обеспечивающего важные взаимодействия, может помочь снизить INP страницы. Однако имейте в виду, что предварительная загрузка слишком большого количества JavaScript во время запуска может привести к непредвиденным негативным последствиям, если слишком много ресурсов борются за пропускную способность.
Вы также должны быть осторожны при разделении кода . Разделение кода — отличная оптимизация для уменьшения объема JavaScript, загружаемого во время запуска, но взаимодействия могут быть отложены, если они полагаются на JavaScript, загружаемый в самом начале взаимодействия. Чтобы компенсировать это, вам необходимо изучить намерения пользователя и внедрить предварительную загрузку необходимых фрагментов JavaScript до того, как произойдет взаимодействие. Одним из примеров может быть предварительная загрузка JavaScript, необходимого для проверки содержимого формы, когда какое-либо из полей формы находится в фокусе.
Заключение
Чтобы повысить скорость страницы, предварительно загрузите важные ресурсы, которые браузер поздно обнаруживает. Предварительная загрузка всего была бы контрпродуктивной, поэтому используйте preload
экономно и измеряйте влияние в реальном мире .