[Перевод] Preload, prefetch и другие теги
Есть много способов повышения веб-производительности. Один из них — предзагрузка контента, который понадобится позже. Префтечинг CSS, предварительный рендеринг полной страницы или резолвинг доменного имени. Делаем всё заранее, а потом мгновенно отображаем результат! Звучит круто.
Ещё круче, что это очень просто реализовано. Пять тегов дают браузеру команду на предварительные действия:
Вкратце расскажем, что они делают и когда их использовать.
Перейти к: preload · prefetch · preconnect · dns-prefetch · prerender
говорит браузеру как можно скорее загрузить и кэшировать ресурс (например, скрипт или таблицу стилей). Это полезно, когда ресурс понадобится через несколько секунд после загрузки страницы — и вы хотите ускорить процесс.
Браузер ничего не делает с ресурсом после загрузки. Скрипты не выполняются, таблицы стилей не применяются. Ресурс просто кэшируется и немедленно предоставляется по запросу.
Синтаксис
href
указывает на ресурс, который вы хотите скачать.
as
может быть чем угодно, что можно скачать в браузере:
style
для таблиц стилей,script
для скриптов,font
для шрифтов,fetch
для ресурсов, загруженных с помощьюfetch()
илиXMLHttpRequest
,- полный список см. на MDN.
Важно указать атрибут as
— это помогает браузеру правильно расставлять приоритеты и планировать загрузку.
Когда использовать
Используйте предзагрузку, когда ресурс понадобится в самое ближайшее время. Например:
- Нестандартные шрифты из внешнего файла:
/* index.css */ @font-face { src: url('comic-sans.woff2') format('woff2'); }
По умолчаниюcomic-sans.woff2
начнёт загружаться только после загрузки и разбораindex.css
. Чтобы не ждать так долго, можно загрузить шрифт раньше с помощью:
- Если вы разделяете свои стили согласно подходу Critical CSS на две части, критическую (для немедленного рендеринга) и некритическую:
При таком подходе некритические стили начнут загружаться только при запуске JavaScript, что может произойти через несколько секунд после рендеринга. Вместо ожидания JS используйте, чтобы начать загрузку раньше:
Не злоупотребляйте предзагрузкой. Если загружать всё подряд, сайт не ускорится волшебным образом, скорее наоборот, это помешает браузеру грамотно планировать работу.
Не путайте с префетчингом. Не используйте , если вам не нужен ресурс сразу после загрузки страницы. Если он понадобится позже, например, для следующей страницы, то используйте
.
Подробности
Это обязательный тег для исполнения браузером (если он его поддерживает), в отличие от всех других тегов , связанных с предварительной загрузкой. Браузер обязан загрузить ресурс, указанный в . В других случаях он может проигнорировать предварительную загрузку, например, если работает на медленном соединении.
Приоритеты. Разным ресурсам (стили, скрипты, шрифты и т. д.), браузеры обычно назначают разные приоритеты, чтобы в первую очередь загружать самые важные ресурсы. В данном случае браузер определяет приоритет по атрибуту as
. Для браузера Chrome можете посмотреть полную таблицу приоритетов.
просит браузер загрузить и кэшировать ресурс (например, скрипт или таблицу стилей) в фоновом режиме. Загрузка происходит с низким приоритетом, поэтому не мешает более важным ресурсам. Это полезно, если ресурс понадобится на следующей странице, а вы хотите заранее его кэшировать.
Здесь тоже браузер ничего не делает с ресурсом после загрузки. Скрипты не выполняются, таблицы стилей не применяются. Ресурс просто кэшируется и немедленно предоставляется по запросу.
Синтаксис
href
указывает на ресурс, который вы хотите скачать.
as
может быть чем угодно, что можно скачать в браузере:
style
для таблиц стилей,script
для скриптов,font
для шрифтов,fetch
для ресурсов, загруженных с помощьюfetch()
илиXMLHttpRequest
,- полный список см. на MDN.
Важно указать атрибут as
— это помогает браузеру правильно расставлять приоритеты и планировать загрузку.
Когда использовать
Для загрузки ресурсов с других страниц, если нужен ресурс с другой страницы, и вы хотите предварительно загрузить его, чтобы потом ускорить рендеринг этой страницы. Например:
- У вас интернет-магазин, и 40% пользователей уходят с главной страницы на страницу товара. Используйте
, загружая файлы CSS и JS для рендеринга страниц с продуктом.
- У вас одностраничное приложение, а разные страницы загружают разные пакеты. Когда пользователь посещает какую-то страницу, можно предварительно загрузить пакеты для всех страниц, на которые она ссылается.
Вероятно, этот тег можно безопасно использовать в любом объёме. Браузеры обычно планируют prefetch с наименьшим приоритетом, так что он никому не мешает. Только имейте в виду, что расходуется трафик пользователя, который может стоить денег.
Не для срочных запросов. Не используйте , когда ресурс понадобится через несколько секунд. В этом случае применяйте
.
Подробности
Необязательный тег. Браузер не обязан следовать этой инструкции, он может проигнорировать её, например, на медленном соединении.
Приоритет в Chrome. В Chrome обычно выполняется с минимальным приоритетом (см. полную таблицу приоритетов), то есть после загрузки всего остального.
просит браузер заранее подключиться к домену, когда вы хотите ускорить установку соединения в будущем.
Браузер должен установить соединение, если извлекает какие-то ресурсы с нового стороннего домена. Например, если загружает шрифты Google Fonts, React из CDN или запрашивает ответ JSON с сервера API.
Установка нового соединения обычно занимает несколько сотен миллисекунд. Она производится один раз, но всё равно отнимает время. Если вы заранее установили соединение, то сэкономите время и быстрее загрузите ресурсы с этого домена.
Синтаксис
href
указывает на доменное имя, для которого нужно определить IP-адрес. Можно указывать с префиксом (https://domain.com
) или без него (//domain.com
).
Когда использовать
Используйте для доменов, которые скоро понадобятся для загрузки оттуда важного стиля, скрипта или изображения, но вы пока не знаете URL ресурса. Например:
- Ваше приложение размещается на
my-app.com
и делает AJAX-запросы кapi.my-app.com
: вы не знаете заранее конкретные запросы, потому что они делатся динамически из JS. Здесь вполне уместно использование тега для предварительного подключения к домену. - Ваше приложение размещается на
my-app.com
и использует шрифты Google Fonts. Они загружаются в два этапа: сначала загружается файл CSS с доменаfonts.googleapis.com
, затем этот файл запрашивает шрифты сfonts.gstatic.com
. Вы не можете знать, какие конкретные файлы шрифтов изfonts.gstatic.com
вам понадобятся, пока не загрузите файл CSS, поэтому заранее мы можем только установить предварительное соединение.
Используйте этот тег, чтобы немного ускорить какой-то сторонний скрипт или стиль за счёт предварительной установки соединения.
Не злоупотребляйте. Установка и поддержание соединения — дорогостоящая операция как для клиента, так и для сервера. Используйте этот тег максимум для 4–6 доменов.
Подробности
Необязательный тег. Браузер не обязан следовать этой инструкции и может проигнорировать её, например, если уже установлено много соединений или в каком-то другом случае.
Что включает в себя процесс подключения. Для подключения к каждому сайту браузер должен выполнить следующие действия:
- Резолвинг DNS. Найти IP-адрес сервера (
216.58.215.78
) для указанного доменного имени (google.com
). - Рукопожатие TCP. Обмен пакетами (клиент → сервер → клиент), чтобы инициировать TCP-соединение с сервером.
- Рукопожатие TLS (только для сайтов HTTPS). Два раунда обмена пакетами (клиент → сервер → клиент → сервер → клиент), чтобы инициировать безопасный сеанс TLS.
Примечание: HTTP/3 улучшит и ускорит механизм рукопожатия, но он ещё далеко.
просит браузер заранее выполнить резолвинг DNS для домена, если вы скоро будете подключаться к нему и хотите ускорить начальное соединение.
Браузер должен определить IP-адрес домена, если будет извлекать какие-то ресурсы с нового стороннего домена. Например, загружать шрифты Google Fonts, React из CDN или запрашивать ответ JSON с сервера API.
Для каждого нового домена разрешение записи DNS обычно занимает около 20−120 мс. Это влияет только на загрузку первого ресурса с данного домена, но всё равно представляет задержку. Если осуществить разрешение DNS заранее, то мы сэкономим время и загрузим ресурс быстрее.
Синтаксис
href
указывает на доменное имя, для которого нужно установить IP-адрес. Можно указывать с префиксом (https://domain.com
) или без него (//domain.com
).
Когда использовать
Используйте для доменов, которые скоро понадобятся для загрузки оттуда ресурсов, о которых браузер не знает заранее. Например:
- Ваше приложение размещается на
my-app.com
и делает AJAX-запросы кapi.my-app.com
: вы не знаете заранее конкретные запросы, потому что они делатся динамически из JS. Здесь вполне уместно использование тега для предварительного подключения к домену. - Ваше приложение размещается на
my-app.com
, и использует шрифты Google Fonts. Они загружаются в два этапа: сначала загружается файл CSS с доменаfonts.googleapis.com
, затем этот файл запрашивает шрифты сfonts.gstatic.com
. Вы не можете знать, какие конкретные файлы шрифтов изfonts.gstatic.com
вам понадобится, пока не загрузите файл CSS, поэтому заранее мы можем только установить предварительное соединение.
Используйте этот тег, чтобы немного ускорить какой-то сторонний скрипт или стиль за счёт предварительной установки соединения.
Обратите внимание схожие характеристики на
и
. Использовать их вместе для одного домена обычно не имеет смысла:
уже включает в себя
и многое другое. Это можно оправдать в двух случаях:
- Вы хотите поддерживать старые браузеры.
поддерживается начиная с IE10 и Safari 5.
некоторое время поддерживался в Chrome и Firefox, но был добавлен в Safari только в 11.1 и по-прежнему не поддерживается в IE/Edge. Если нужно поддерживать эти браузеры, используйте
в качестве запасного варианта для
.
- Вы хотите ускорить подключение более чем к 4−6 доменам. Тег
не рекомендуется использовать более чем с 4−6 доменами, так как установка и поддержание соединения — дорогостоящая операция.
потребляет меньше ресурсов, поэтому в случае необходимости используйте его.
Подробности
Необязательный тег. Браузер не обязан следовать этой инструкции, поэтому может не выполнять резолвинг DNS, например, если на странице много таких тегов или в каком-то другом случае.
Что такое DNS. Каждому серверу в интернете соответствует уникальный IP-адрес, который выглядит как 216.58.215.78
. В адресной строке браузера обычно вводится название сайта (например, google.com
), а серверы DNS (Domain Name System) сопоставляют его с IP-адресом сервера (216.58.215.78
).
Чтобы определить IP-адрес, браузер должен выполнить запрос к DNS-серверу. Он занимает 20−120 мс при подключении к новому стороннему домену.
DNS кэшируется, хотя и не очень надёжно. Некоторые ОС и браузеры кэшируют DNS-запросы: это сэкономит время при повторных запросах, но на кэширование нельзя полагаться. В Linux оно обычно вообще не работает. У Chrome есть кэш DNS, но он живёт только минуту. Windows кэширует DNS-ответы в течение пяти дней.
просит браузер загрузить URL-адрес и отобразить его на невидимой вкладке. Когда пользователь нажимает на ссылку, страница должна отобразиться немедленно. Это полезно, если вы уверены, что пользователь посетит определённую страницу, и хотите ускорить её отображение.
Несмотря на исключительную эффективность этого тега (или из-за неё), в 2019 году плохо поддерживается основными браузерах. Подробнее см. ниже.
Синтаксис
href
указывает на URL, для который вы хотите запустить рендеринг в фоновом режиме.
Когда использовать
Когда вы действительно уверены, что пользователь перейдёт на определённую страницу. Если у вас «туннель», по которому 70% посетителей страницы A переходят на страницу Б, то на странице А поможет очень быстро отобразить страницу Б.
Не злоупотребляйте. Предварительный рендеринг чрезвычайно дорого обходится с точки зрения трафика и памяти. Не используйте более чем для одной страницы.
Подробности
Необязательный тег. Браузер не обязан следовать этой инструкции и может проигнорировать её, например, на медленном соединении или при недостаточном объёме свободной памяти.
Ради экономии памяти Chrome не выполняет полный рендеринг, а только предзагрузку NoState. Это означает, что Chrome загружает страницу и все её ресурсы, но не делает рендеринг и не выполняет JavaScript.
Firefox и Safari вообще не поддерживают этот тег. Это не нарушает спецификацию, так как браузеры не обязаны выполнять данную инструкцию;, но всё равно печально. Баг реализации в Firefox был открыт в течение семи лет. Есть сообщения, что Safari тоже не поддерживает этот тег.
Используйте:
— когда вам понадобится ресурс через несколько секунд
— когда понадобится ресурс на следующей странице
— когда вы знаете, что вам скоро понадобится ресурс, но вы ещё не знаете его полный URL
— аналогично, когда вы знаете, что вам скоро понадобится ресурс, но вы ещё не знаете его полный URL (для старых браузеров)
— когда вы уверены, что пользователи перейдут на определённую страницу, и хотите ускорить её отображение