Что такое precaching и когда он нужен

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

В Workbox precaching реализован через модуль workbox-precaching, который предоставляет удобный API для определения списка ресурсов и управления их кэшированием.


Список ресурсов для precaching

Ресурсы, подлежащие precaching, обычно задаются в виде массива объектов, где каждый объект содержит URL ресурса и его ревизию. Ревизия (revision) — это уникальный идентификатор версии файла, чаще всего хеш содержимого файла. Она позволяет Service Worker определять, изменился ли файл, и при необходимости обновлять кэш.

Пример структуры ресурса для precaching:

[
  { url: '/index.html', revision: 'a1b2c3d4' },
  { url: '/styles/main.css', revision: 'e5f6g7h8' },
  { url: '/scripts/app.js', revision: 'i9j0k1l2' }
]

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


Настройка precaching в Workbox

Основная функция для работы с precaching — precacheAndRoute(). Она принимает массив ресурсов и автоматически создает маршруты в Service Worker, обеспечивающие отдачу кэшированных файлов.

Пример использования:

import { precacheAndRoute } from 'workbox-precaching';

precacheAndRoute([
  { url: '/index.html', revision: 'a1b2c3d4' },
  { url: '/styles/main.css', revision: 'e5f6g7h8' },
  { url: '/scripts/app.js', revision: 'i9j0k1l2' }
]);

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


Автоматическое управление кэшем

Workbox поддерживает стратегию обновления кэша при изменении ресурсов. Если версия файла (ревизия) изменилась, Service Worker удаляет старую версию из кэша и добавляет новую. Это позволяет гарантировать, что пользователи всегда получают актуальную версию приложения.

// Новый файл с измененной ревизией
precacheAndRoute([
  { url: '/index.html', revision: 'z9y8x7w6' } // новая версия
]);

При следующей активации Service Worker старый index.html будет заменен на новый, без необходимости вмешательства разработчика.


Когда precaching необходим

Precaching оптимально использовать для:

  1. Основных страниц и шаблонов — index.html, базовые стили и скрипты.
  2. Статических ресурсов, которые редко меняются: логотипы, шрифты, изображения интерфейса.
  3. Ресурсов, критичных для офлайн-режима — чтобы приложение могло корректно работать без подключения к сети.

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


Интеграция с инструментами сборки

Workbox позволяет автоматически генерировать список ресурсов для precaching на этапе сборки. Это делается с помощью CLI или плагинов для сборщиков, например:

  • workbox-webpack-plugin для Webpack
  • workbox-build для любых других сборок

Пример использования с Webpack:

const { InjectManifest } = require('workbox-webpack-plugin');

module.exports = {
  plugins: [
    new InjectManifest({
      swSrc: './src/sw.js', // исходный Service Worker
      swDest: 'service-worker.js',
      maximumFileSizeToCacheInBytes: 5 * 1024 * 1024
    })
  ]
};

Плагин автоматически добавляет все указанные в сборке файлы в precache-манифест, генерирует ревизии и интегрирует их в Service Worker.


Оптимизация precaching

  • Минимизировать количество файлов: precaching полезен для критичных ресурсов, но слишком большой кэш замедляет установку Service Worker.
  • Использовать ревизии на основе хеша содержимого: это гарантирует, что обновления ресурсов корректно фиксируются.
  • Комбинировать с runtime caching: ресурсы, которые часто изменяются, лучше обслуживать через динамическое кэширование с подходящей стратегией (NetworkFirst, StaleWhileRevalidate).

Взаимодействие с другими стратегиями

Precaching в Workbox не конфликтует с runtime caching. Можно задать маршруты для API-запросов, динамических изображений или данных, одновременно поддерживая precaching для статических ресурсов. Это создает гибкую архитектуру кэширования, где:

  • Статические файлы доставляются мгновенно (precaching).
  • Динамические данные обновляются по мере необходимости (runtime caching).