[Перевод] 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 можете посмотреть полную таблицу приоритетов.

i2bfvijtqhb3wt6cnkcskwc55ew.png


просит браузер загрузить и кэшировать ресурс (например, скрипт или таблицу стилей) в фоновом режиме. Загрузка происходит с низким приоритетом, поэтому не мешает более важным ресурсам. Это полезно, если ресурс понадобится на следующей странице, а вы хотите заранее его кэшировать.

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

Синтаксис



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 (для старых браузеров)
  •  — когда вы уверены, что пользователи перейдут на определённую страницу, и хотите ускорить её отображение

© Habrahabr.ru