Предварительное кэширование, что можно и чего нельзя делать

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

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

Что нужно делать: предварительно кэшировать важные статические ресурсы

Лучшими кандидатами на предварительное кэширование являются критически важные статические ресурсы, но что считается «критическим» активом? С точки зрения разработчика может показаться заманчивым думать о всем приложении как о «критическом», но наиболее важна точка зрения пользователя. Думайте о критических ресурсах как о тех, которые совершенно необходимы для обеспечения удобства взаимодействия с пользователем:

  • Глобальные таблицы стилей.
  • Файлы JavaScript, обеспечивающие глобальную функциональность.
  • HTML оболочки приложения, если это применимо к вашей архитектуре.

Напоминание: это общие рекомендации, а не жесткие рекомендации. При предварительном кэшировании ресурсов лучше склоняться к меньшему, а не к большему предварительному кэшированию.

Что нужно делать: предварительно кэшировать резервный автономный режим для многостраничных веб-сайтов.

Для типичных многостраничных веб-сайтов вы можете полагаться на стратегию кэширования «сначала сеть» или «только сеть» для обработки навигационных запросов.

В таких случаях вам нужно убедиться, что ваш сервис-воркер осуществляет предварительное кэширование и отвечает автономной резервной страницей, когда пользователь делает запрос навигации в автономном режиме. Одним из способов сделать это в Workbox может быть использование стратегии только для сети с резервным режимом в автономном режиме, а также с использованием предварительной загрузки навигации :

import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute, Route} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
import * as navigationPreload from 'workbox-navigation-preload';

navigationPreload.enable();

// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);

// The network-only callback should match navigation requests, and
// the handler for the route should use the network-only strategy, but
// fall back to a precached offline page in case the user is offline.
const networkOnlyNavigationRoute = new Route(({request}) => {
  return request.mode === 'navigate';
}, new NetworkOnly({
  plugins: [
    new PrecacheFallbackPlugin({
      fallbackURL: '/offline.html'
    })
  ]
}));

registerRoute(networkOnlyNavigationRoute);

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

Возможно, стоит: рассмотреть возможность спекулятивного предварительного кэширования.

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

Теперь большое предостережение: будьте очень осторожны, если решите это сделать. При этом легко потерять данные, и это должно быть решение, основанное на данных. Кроме того, избегайте спекулятивного предварительного кэширования ресурсов, которые часто меняются, поскольку пользователю придется использовать дополнительные данные каждый раз, когда код предварительного кэширования обнаруживает новую версию. Наблюдайте за потоками пользователей в своей аналитике, чтобы увидеть, куда пользователи обычно направляются. Если у вас есть какие-либо сомнения по поводу спекулятивного предварительного кэширования активов, возможно, это хороший знак не делать этого.

Может быть, и нет: предварительное кэширование статического HTML

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

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

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

Не делайте предварительное кэширование адаптивных изображений или значков.

Это не столько общее указание, сколько правило. Адаптивные изображения — это комплексное решение сложной проблемы: у вас много пользователей на многих устройствах, каждое из которых различается по размеру экрана, плотности пикселей и поддержке альтернативных форматов. Если вы предварительно кэшируете весь набор адаптивных изображений, вы, вероятно, предварительно кэшируете несколько изображений, тогда как пользователь может в конечном итоге загрузить только одно из них.

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

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

Не делайте предварительное кэширование полифилов.

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

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

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

Заключение

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

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