Preload, prefetch та інші теги

є багато способів підвищення веб-продуктивності. Один із них — передзавантаження контенту, який знадобиться пізніше. Префтечінг CSS, попередній рендеринг повної сторінки або резолвінг доменного імені. Робимо все заздалегідь, а потім миттєво відображаємо результат! Звучить круто.

Ще крутіше, що це дуже просто реалізовано. П'ять тегів дають браузеру команду на попередні дії:

<link rel="prefetch" href="/uk/style.css" as="style" />
<link rel="preload" href="/uk/style.css" as="style" />

<link rel="preconnect" href="https://example.com" />
<link rel="dns-prefetch" href="https://example.com" />

<link rel="prerender" href="https://example.com/about.html" />


Коротко розповімо, що вони роблять і коли їх використати.

Перейти до: попереднє навантаження · попередній вибір · попереднє підключення · dns-prefetch · prerender

попереднє навантаження

<link rel= "preload"> говорить браузеру якнайшвидше завантажити та кешувати ресурс (наприклад, скрипт або таблицю стилів). Це корисно, коли ресурс знадобиться за кілька секунд після завантаження сторінки — і ви хочете прискорити процес.

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

Синтаксис

<link rel="preload" href="/uk/style.css" as="style" />

href вказує на ресурс, який ви бажаєте завантажити.

as може бути чим завгодно, що можна завантажити в браузері:

  • style для таблиць стилів,
  • script для скриптів,
  • font для шрифтів,
  • fetch для ресурсів, завантажених за допомогою fetch() або XMLHttpRequest,
  • повний список див. на MDN.

Важливо вказати атрибут as - Це допомагає браузеру правильно розставляти пріоритети та планувати завантаження.

коли використовувати

Використовуйте попереднє завантаження, коли ресурс знадобиться найближчим часом. Наприклад:

  • Нестандартні шрифти із зовнішнього файлу:
    <!-- index.html -->
    <link rel="stylesheet" href="index.css" />
    /* index.css */
    @font-face {
      src: url('comic-sans.woff2') format('woff2');
    }

    За замовчуванням comic-sans.woff2 почне завантажуватися тільки після завантаження та розбору index.css. Щоб не чекати так довго, можна завантажити шрифт раніше за допомогою <link rel= "preload">:

    <link rel="preload" href="comic-sans.woff2" as="font" />
  • Якщо ви поділяєте свої стилі згідно з підходом Критичний CSS на дві частини, критичну (для негайного рендерингу) та некритичну:
    <style>
    /* Inlined critical styles */
    </style>
    
    <script>
    /* Custom JS that starts downloading non-critical styles */
    loadCSS('/app/non-critical.css');
    </script>

    При такому підході некритичні стилі почнуть завантажуватись лише при запуску JavaScript, що може статися через кілька секунд після рендерингу. Замість очікування JS використовуйте <link rel= "preload">, щоб розпочати завантаження раніше:

    <style>
    /* Inlined critical styles */
    </style>
    
    <link rel="preload" href="/uk/app/non-critical.css" as="style" />
    
    <script>
    /* Custom JS that starts downloading non-critical styles */
    loadCSS('/app/non-critical.css');
    </script>

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

Не плутайте з префетчингом. Не використовуйте <link rel= "preload">Якщо вам не потрібен ресурс відразу після завантаження сторінки. Якщо він знадобиться пізніше, наприклад, для наступної сторінки, використовуйте <link rel= "prefetch">.

подробиці

Це обов'язковий тег для виконання браузером (якщо він його підтримує), на відміну від інших тегів , пов'язаних із попереднім завантаженням. Браузер повинен завантажити ресурс, зазначений у <link rel="preload">. В інших випадках може проігнорувати попереднє завантаження, наприклад, якщо працює на повільному з'єднанні.

пріоритети. Різним ресурсам (стилі, скрипти, шрифти тощо), браузери зазвичай призначають різні пріоритети, щоб у першу чергу завантажувати найважливіші ресурси. У цьому випадку браузер визначає пріоритет за атрибутом as. Для браузера Chrome можна переглянути повну таблицю пріоритетів.

Preload, prefetch та інші теги

попередній вибір

<link rel= "prefetch"> просить браузер завантажити та кешувати ресурс (наприклад, скрипт чи таблицю стилів) у фоновому режимі. Завантаження відбувається з низьким пріоритетом, тому не заважає найважливішим ресурсам. Це корисно, якщо ресурс знадобиться на наступній сторінці, а ви хочете заздалегідь кешувати його.

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

Синтаксис

<link rel="prefetch" href="/uk/style.css" as="style" />

href вказує на ресурс, який ви бажаєте завантажити.

as може бути чим завгодно, що можна завантажити в браузері:

  • style для таблиць стилів,
  • script для скриптів,
  • font для шрифтів,
  • fetch для ресурсів, завантажених за допомогою fetch() або XMLHttpRequest,
  • повний список див. на MDN.

Важливо вказати атрибут as - Це допомагає браузеру правильно розставляти пріоритети та планувати завантаження.

коли використовувати

Для завантаження ресурсів з інших сторінок, якщо потрібен ресурс з іншої сторінки, і ви хочете завантажити його, щоб потім прискорити рендеринг цієї сторінки. Наприклад:

  • У вас інтернет-магазин і 40% користувачів йдуть з головної сторінки на сторінку товару. Використовуйте <link rel= "prefetch">, завантажуючи файли CSS та JS для рендерингу сторінок із продуктом.
  • У вас є односторінковий додаток, а різні сторінки завантажують різні пакети. Коли користувач відвідує якусь сторінку, можна завантажити пакети для всіх сторінок, на які вона посилається.

Ймовірно, цей тег можна безпечно використовувати у будь-якому обсязі. Браузери зазвичай планують prefetch з найменшим пріоритетом, тому він нікому не заважає. Тільки майте на увазі, що витрачається трафік користувача, який може коштувати гроші.

Не для термінових запитів. Не використовуйте <link rel= "prefetch">, коли ресурс знадобиться за кілька секунд. У цьому випадку застосовуйте <link rel= "preload">.

подробиці

Необов'язковий тег. Браузер ні слідувати цієї інструкції, може проігнорувати її, наприклад, на повільному соединении.

Пріоритет у Chrome. У Chrome <link rel= "prefetch"> зазвичай виконується з мінімальним пріоритетом (див. повну таблицю пріоритетів), тобто після завантаження решти.

попереднє підключення

<link rel= "preconnect"> просить браузер заздалегідь підключитися до домену, коли хочете прискорити встановлення з'єднання у майбутньому.

Браузер повинен встановити з'єднання, якщо виймає якісь ресурси з нового стороннього домену. Наприклад, якщо завантажує шрифти Google Fonts, React із CDN або запитує відповідь JSON із сервера API.

Встановлення нового з'єднання зазвичай займає кілька сотень мілісекунд. Вона проводиться один раз, але все одно забирає час. Якщо ви заздалегідь встановили з'єднання, заощадите час і швидше завантажте ресурси з цього домену.

Синтаксис

<link rel= "preconnect" href="https://api.my-app.com" />

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-prefetch

<link rel= "dns-prefetch"> просить браузер заздалегідь виконати резолвінг DNS для домену, якщо ви скоро підключатиметеся до нього і хочете прискорити початкове з'єднання.

Браузер повинен визначити IP-адресу домену, якщо витягуватиме якісь ресурси з нового стороннього домену. Наприклад, завантажувати шрифти Google Fonts, React із CDN або запитувати відповідь JSON із сервера API.

Для кожного нового домену роздільна здатність запису DNS зазвичай займає близько 20-120 мс. Це впливає лише на завантаження першого ресурсу з даного домену, але все одно становить затримку. Якщо здійснити дозвіл DNS заздалегідь, ми заощадимо час і завантажимо ресурс швидше.

Синтаксис

<link rel= "dns-prefetch" href="https://api.my-app.com" />

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, тому заздалегідь ми можемо лише встановити попереднє з'єднання.

Використовуйте цей тег, щоб трохи прискорити якийсь сторонній скрипт чи стиль рахунок попередньої установки з'єднання.

Зверніть увагу схожі характеристики на <link rel= "dns-prefetch"/> и <link rel= "preconnect">. Використовувати їх разом для одного домену зазвичай не має сенсу: <link rel= "preconnect"> вже включає в себе <link rel= "dns-prefetch"/> і багато іншого. Це можна виправдати у двох випадках:

  • Ви хочете підтримувати старі браузери. <link rel= "dns-prefetch" /> підтримується починаючи з IE10 та Safari 5. <link rel= "preconnect"> деякий час підтримувався в Chrome та Firefox, але був доданий у Safari лише в 11.1 та як і раніше не підтримується в IE/Edge. Якщо потрібно підтримувати ці браузери, використовуйте <link rel= "dns-prefetch" /> як запасний варіант для <link rel= "preconnect">.
  • Ви хочете прискорити підключення до 4-6 доменів.. Тег <link rel= "preconnect"> не рекомендується використовувати з більш ніж 4-6 доменами, оскільки встановлення та підтримка з'єднання — дорога операція. <link rel= "dns-prefetch" /> споживає менше ресурсів, тому у разі потреби використовуйте його.

подробиці

Необов'язковий тег. Браузер не повинен дотримуватися цієї інструкції, тому може не виконувати резолвінг 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-відповіді протягом п'яти днів.

prerender

<link rel= "prerender"> просить браузер завантажити URL-адресу і відобразити її на невидимій вкладці. Коли користувач натискає посилання, сторінка повинна відобразитися негайно. Це корисно, якщо ви впевнені, що користувач відвідає певну сторінку, і ви хочете прискорити її відображення.

Незважаючи на виняткову ефективність цього тега (або через неї), у 2019 році <link rel= "prerender"> погано підтримується основними браузерами. Детальніше див. нижче.

Синтаксис

<link rel="prerender" href="https://my-app.com/pricing" />

href вказує на URL, для якого ви хочете запустити рендеринг у фоновому режимі.

коли використовувати

Коли ви дійсно впевнені, що користувач перейде на певну сторінку. Якщо у вас «тунель», яким 70% відвідувачів сторінки A переходять на сторінку Б, то <link rel= "prerender"> на сторінці А допоможе швидко відобразити сторінку Б.

Не зловживайте. Попередній рендеринг надзвичайно дорого обходиться з погляду трафіку та пам'яті. Не використовуйте <link rel= "prerender"> більш ніж однієї сторінки.

подробиці

Необов'язковий тег. Браузер не повинен дотримуватись цієї інструкції і може проігнорувати її, наприклад, на повільному з'єднанні або при недостатньому об'ємі вільної пам'яті.

Заради економії пам'яті Chrome не виконує повний рендеринг, а тільки передзавантаження NoState. Це означає, що Chrome завантажує сторінку та її ресурси, але не робить рендеринг і не виконує JavaScript.

Firefox та Safari взагалі не підтримують цей тег. Не порушує специфікацію, оскільки браузери нічого не винні виконувати дану інструкцію; але все одно сумно. Баг реалізації Firefox був відкритий протягом семи років. Є повідомлення, що Safari також не підтримує цей тег.

Резюме

Використовуйте:

  • <link rel= "preload"> - коли вам знадобиться ресурс за кілька секунд
  • <link rel= "prefetch"> - коли знадобиться ресурс на наступній сторінці
  • <link rel= "preconnect"> — коли ви знаєте, що вам скоро знадобиться ресурс, але ви ще не знаєте його повну URL-адресу
  • <link rel= "dns-prefetch"> — аналогічно, коли ви знаєте, що вам скоро знадобиться ресурс, але ви ще не знаєте його повну URL-адресу (для старих браузерів)
  • <link rel= "prerender"> — коли ви впевнені, що користувачі перейдуть на певну сторінку та хочете прискорити її відображення

Джерело: habr.com

Додати коментар або відгук