Codelab: предварительная загрузка критически важных ресурсов для повышения скорости загрузки

В этой лаборатории производительность следующей веб-страницы улучшена за счет предварительной загрузки и предварительной выборки нескольких ресурсов:

Скриншот приложения

Мера

Прежде чем добавлять какие-либо оптимизации, сначала измерьте производительность веб-сайта.

  • Чтобы просмотреть сайт, нажмите «Просмотреть приложение» . Затем нажмите Полноэкранный режим полноэкранный .

Запустите аудит производительности Lighthouse ( Lighthouse > Параметры > Производительность ) на работающей версии вашего Glitch (см. также Откройте для себя возможности повышения производительности с помощью Lighthouse ).

Lighthouse показывает следующий неудачный аудит ресурса, который был получен с опозданием:

Lighthouse: аудит запросов на предзагрузку ключей
  • Нажмите «Control+Shift+J» (или «Command+Option+J» на Mac), чтобы открыть DevTools.
  • Откройте вкладку «Сеть» .
Сетевая панель с поздно обнаруженным ресурсом

Файл main.css не извлекается элементом Link ( <link> ), помещенным в документ HTML, но отдельный файл JavaScript, fetch-css.js , присоединяет элемент Link к DOM после события window.onLoad . Это означает, что файл извлекается только после того, как браузер завершит анализ и выполнение файла JS. Аналогично, веб-шрифт ( K2D.woff2 ), указанный в main.css , извлекается только после завершения загрузки файла CSS.

Цепочка критических запросов представляет собой порядок ресурсов, которым присвоен приоритет и которые извлекаются браузером. На данный момент эта веб-страница выглядит так:

├─┬ / (initial HTML file)
  └── fetch-css.js
    └── main.css
      └── K2D.woff2

Поскольку файл CSS находится на третьем уровне цепочки запросов, Lighthouse определил его как поздно обнаруженный ресурс.

Предварительная загрузка критически важных ресурсов

Файл main.css — это критически важный ресурс, который необходим сразу после загрузки страницы. Для важных файлов, таких как этот ресурс, которые поздно загружаются в вашем приложении, используйте тег предварительной загрузки ссылки, чтобы сообщить браузеру о необходимости загрузки раньше, добавив элемент Link в заголовок документа.

Добавьте тег предварительной загрузки для этого приложения:

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
</head>

Атрибут as используется для определения типа извлекаемого ресурса, а as="style" используется для предварительной загрузки файлов таблицы стилей.

Перезагрузите приложение и посмотрите на панель «Сеть» в DevTools.

Сетевая панель с предварительно загруженным ресурсом

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

Если использовать предварительную загрузку неправильно, она может снизить производительность, создавая ненужные запросы к ресурсам, которые не используются. В этом приложении details.css — это еще один CSS-файл, расположенный в корне проекта, но используемый для отдельного /details route . Чтобы показать пример неправильного использования предварительной загрузки, добавьте также подсказку по предварительной загрузке для этого ресурса.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Перезагрузите приложение и посмотрите на панель «Сеть» . Выполняется запрос на получение details.css , даже если он не используется веб-страницей.

Сетевая панель с ненужной предварительной загрузкой

Chrome отображает предупреждение на панели консоли , если предварительно загруженный ресурс не используется страницей в течение нескольких секунд после его загрузки.

Предупреждение о предварительной загрузке в консоли

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

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Список всех типов ресурсов, которые можно получить, а также правильные значения, которые следует использовать для атрибута as , см. в статье MDN о предварительной загрузке .

Предварительная загрузка будущих ресурсов

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

На этом веб-сайте щелчок по изображению приведет вас к отдельной details/ маршруту.

Подробности маршрута

Отдельный файл CSS details.css содержит все стили, необходимые для этой простой страницы. Добавьте элемент ссылки в index.html для предварительной загрузки этого ресурса.

<head>
  <!-- ... -->
  <link rel="prefetch" href="details.css">
</head>

Чтобы понять, как это вызывает запрос файла, откройте панель «Сеть» в DevTools и снимите флажок «Отключить кеш» .

Отключить кеш в Chrome DevTools

Перезагрузите приложение и обратите внимание, как запрос details.css выполняется с очень низким приоритетом после того, как все остальные файлы были получены.

Сетевая панель с предварительно загруженным ресурсом

Открыв DevTools, щелкните изображение на веб-сайте, чтобы перейти на страницу details . Поскольку элемент link используется в details.html для получения details.css , запрос к ресурсу выполняется, как и ожидалось.

Сетевые запросы на странице сведений

Щелкните сетевой запрос details.css в DevTools, чтобы просмотреть его сведения. Вы заметите, что файл извлекается из дискового кеша браузера.

Запрос сведений получен из дискового кэша.

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

Предварительная загрузка и предварительная выборка с помощью веб-пакета

В статье «Уменьшение полезной нагрузки JavaScript с помощью разделения кода» рассматривается использование динамического импорта для разделения пакета на несколько фрагментов. Это демонстрируется на примере простого приложения, которое динамически импортирует модуль из Lodash при отправке формы.

Приложение Magic Sorter, демонстрирующее разделение кода

Вы можете получить доступ к Glitch для этого приложения здесь .

Следующий блок кода, который находится в src/index.js, отвечает за динамический импорт метода при нажатии кнопки.

form.addEventListener("submit", e => {
  e.preventDefault()
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

Разделение пакета сокращает время загрузки страницы за счет уменьшения ее первоначального размера. Версия 4.6.0 веб-пакета обеспечивает поддержку предварительной загрузки или предварительной выборки фрагментов, которые импортируются динамически. Используя это приложение в качестве примера, метод lodash можно предварительно загрузить во время простоя браузера; когда пользователь нажимает кнопку, загрузка ресурса не происходит.

Используйте специальный параметр комментария webpackPrefetch в динамическом импорте для предварительной выборки определенного фрагмента. Вот как это будет выглядеть с этим конкретным приложением.

form.addEventListener("submit", e => {
  e.preventDefault()
  import(/* webpackPrefetch: true */ 'lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

После перезагрузки приложения веб-пакет вставляет тег предварительной выборки для ресурса в заголовок документа. Это можно увидеть на панели «Элементы» в DevTools.

Панель «Элементы» с тегом предварительной загрузки

Наблюдение за запросами на панели «Сеть» также показывает, что этот фрагмент извлекается с низким приоритетом после того, как были запрошены все остальные ресурсы.

Сетевая панель с предварительно загруженным запросом

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

import(/* webpackPreload: true */ 'module')

Заключение

Благодаря этой лаборатории кода вы должны иметь четкое представление о том, как предварительная загрузка или предварительная выборка определенных ресурсов может улучшить взаимодействие с пользователем вашего сайта. Важно отметить, что эти методы не следует использовать для каждого ресурса, и неправильное их использование может снизить производительность. Наилучшие результаты достигаются только при выборочной предварительной загрузке или предварительной выборке.

Обобщить:

  • Используйте предварительную загрузку для ресурсов, которые обнаруживаются поздно, но имеют решающее значение для текущей страницы.
  • Используйте предварительную выборку для ресурсов, которые необходимы для будущего маршрута навигации или действий пользователя.

Не все браузеры в настоящее время поддерживают как предварительную загрузку, так и предварительную выборку. Это означает, что не все пользователи вашего приложения могут заметить улучшение производительности.

Если вам нужна дополнительная информация о конкретных аспектах того, как предварительная загрузка и предварительная загрузка могут повлиять на вашу веб-страницу, обратитесь к этим статьям: