Два способа предварительной загрузки: <link> теги и HTTP-заголовки

Демиан Рензулли
Demián Renzulli

В этой лабораторной работе вы реализуете предварительную выборку двумя способами: с помощью <link rel="prefetch"> и с помощью заголовка HTTP Link .

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

Измерить производительность

Сначала установите базовые показатели:

  1. Нажмите `Control+Shift+J` (или `Command+Option+J` на Mac), чтобы открыть DevTools.
  2. Откройте вкладку Сеть .

  3. В раскрывающемся списке «Регулирование » выберите значение «Быстрый 3G» , чтобы имитировать медленный тип соединения.

  4. Чтобы загрузить страницу продукта, нажмите «Купить сейчас» в примере приложения.

Загрузка страницы product-details.html занимает около 600 мс:

Сетевая панель, показывающая время загрузки product-details.html

Чтобы улучшить навигацию, вставьте тег prefetch на целевую страницу для предварительной загрузки страницы product-details.html :

  • Добавьте следующий элемент <link> в заголовок файла views/index.html :
<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">

      <link rel="prefetch" href="/product-details.html" as="document">
      ...
</head>

Атрибут as необязателен, но рекомендуется к использованию; он помогает браузеру устанавливать правильные заголовки и определять, находится ли ресурс в кэше. Примеры значений этого атрибута: document , script , style , font , image и другие .

Чтобы проверить работу предварительной выборки:

  1. Нажмите `Control+Shift+J` (или `Command+Option+J` на Mac), чтобы открыть DevTools.
  2. Откройте вкладку Сеть .

  3. В раскрывающемся списке «Регулирование » выберите значение «Быстрый 3G» , чтобы имитировать медленный тип соединения.

  4. Снимите флажок Отключить кэш.

  5. Перезагрузите приложение.

Теперь при загрузке целевой страницы страница product-details.html тоже загружается, но с самым низким приоритетом:

Сетевая панель, на которой отображается предварительно загруженный файл product-details.html.

Страница хранится в HTTP-кеше в течение пяти минут, после чего применяются стандартные правила Cache-Control для документа. В данном случае у product-details.html есть заголовок cache-control со значением public, max-age=0 , что означает, что страница хранится в общей сложности пять минут.

Переоценить производительность

  1. Перезагрузите приложение.
  2. Чтобы загрузить страницу продукта, нажмите «Купить сейчас» в примере приложения.

Взгляните на панель «Сеть» . По сравнению с исходной трассировкой сети есть два отличия:

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

Это примерно на 98% меньше, чем в предыдущей версии, которая занимала около 600 мс.

Сетевая панель, на которой показан файл product-details.html, извлеченный из кэша предварительной выборки.

Дополнительный балл: использование prefetch в качестве прогрессивного улучшения

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

Чтобы реализовать адаптивную предварительную выборку, сначала удалите тег <link rel="prefetch"> из views/index.html :

<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
       <link rel="prefetch" href="/product-details.html" as="document">
       ...
    </head>

Затем добавьте следующий код в public/script.js чтобы объявить функцию, которая динамически внедряет тег prefetch , когда пользователь использует быстрое соединение:

function injectLinkPrefetchIn4g(url) {
    if (window.navigator.connection.effectiveType === '4g') {
        //generate link prefetch tag
        const linkTag = document.createElement('link');
        linkTag.rel = 'prefetch';
        linkTag.href = url;
        linkTag.as = 'document';

        //inject tag in the head of the document
        document.head.appendChild(linkTag);
    }
}

Функция работает следующим образом:

  • Он проверяет свойство efficientType API сетевой информации, чтобы определить, использует ли пользователь соединение 4G (или более быстрое).
  • Если это условие выполняется, он генерирует тег <link> с prefetch в ​​качестве типа подсказки, передает URL-адрес, который будет предварительно загружен, в атрибуте href и указывает, что ресурс является HTML- document в атрибуте as .
  • Наконец, он динамически вставляет скрипт в head страницы.

Затем добавьте script.js в views/index.html , непосредственно перед закрывающимся тегом </body> :

<body>
      ...
      <script src="/script.js"></script>
</body>

Запрос script.js в конце страницы гарантирует, что он будет загружен и выполнен после анализа и загрузки страницы.

Чтобы убедиться, что предварительная выборка не мешает критически важным ресурсам текущей страницы, добавьте следующий фрагмент кода для вызова injectLinkPrefetchIn4g() в событии window.load :

<body>
      ...
      <script src="/script.js"></script>
      <script>
           window.addEventListener('load', () => {
                injectLinkPrefetchIn4g('/product-details.html');
           });
      </script>
</body>

Теперь целевая страница предварительно загружает product-details.html только при быстром подключении. Чтобы убедиться в этом:

  1. Нажмите `Control+Shift+J` (или `Command+Option+J` на Mac), чтобы открыть DevTools.
  2. Откройте вкладку Сеть .
  3. В раскрывающемся списке Регулирование выберите Онлайн .
  4. Перезагрузите приложение.

Вы должны увидеть product-details.html на панели «Сеть»:

Сетевая панель, на которой отображается предварительно загруженный файл product-details.html.

Чтобы убедиться, что страница продукта не загружается предварительно при медленном подключении:

  1. В раскрывающемся списке «Регулирование» выберите «Медленный 3G» .
  2. Перезагрузите приложение.

Панель «Сеть» должна включать только ресурсы для целевой страницы без product-details.html :

Сетевая панель показывает, что файл product-details.html не загружается предварительно.

HTTP-заголовок Link можно использовать для предварительной загрузки ресурсов того же типа, что и тег link . Решение о том, когда использовать тот или иной вариант, зависит от ваших предпочтений, поскольку разница в производительности незначительна. В данном случае вы будете использовать его для предварительной загрузки основного CSS-кода страницы товара, чтобы улучшить её рендеринг.

Добавьте заголовок HTTP Link для style-product.css в ответ сервера для целевой страницы:

  1. Откройте файл server.js и найдите обработчик get() для корневого URL: / .
  2. Добавьте следующую строку в начало обработчика:
app.get('/', function(request, response) {
    response.set('Link', '</style-product.css>; rel=prefetch');
    response.sendFile(__dirname + '/views/index.html');
});
  1. Нажмите `Control+Shift+J` (или `Command+Option+J` на Mac), чтобы открыть DevTools.
  2. Откройте вкладку Сеть .
  3. Перезагрузите приложение.

Файл style-product.css теперь предварительно загружается с самым низким приоритетом после загрузки целевой страницы:

Сетевая панель, на которой отображается предварительно загруженный style-product.css.

Чтобы перейти на страницу продукта, нажмите «Купить сейчас» . Взгляните на панель «Сеть» :

Сетевая панель, на которой показан style-product.css, извлеченный из кэша предварительной выборки.

Файл style-product.css извлекается из «предварительного кэша», и его загрузка заняла всего 12 мс.