Версионирование кэша

Основные концепции

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

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

const CACHE_NAME = 'my-app-cache-v1';

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

Стратегии кэширования с версионированием

Workbox поддерживает несколько стратегий кэширования, каждая из которых может сочетаться с версионированием:

  1. Cache First Используется, когда приоритет отдаётся локальному кэшу, а сеть нужна только при отсутствии ресурса. Пример с версионированным кэшем:
workbox.routing.registerRoute(
  ({request}) => request.destination === 'script',
  new workbox.strategies.CacheFirst({
    cacheName: 'js-cache-v2',
    plugins: [
      new workbox.expiration.ExpirationPlugin({
        maxEntries: 50,
        maxAgeSeconds: 7 * 24 * 60 * 60, // 7 дней
      }),
    ],
  })
);
  1. Network First Приоритет отдаётся сети, кэш используется как резерв. Полезно для данных, которые часто обновляются. Версионированные кэши позволяют безопасно обновлять ресурсы без риска загрузки устаревшей информации:
workbox.routing.registerRoute(
  ({request}) => request.destination === 'document',
  new workbox.strategies.NetworkFirst({
    cacheName: 'html-cache-v3',
    plugins: [
      new workbox.expiration.ExpirationPlugin({
        maxEntries: 20,
      }),
    ],
  })
);
  1. Stale While Revalidate Возвращает кэшированную версию мгновенно, а сеть проверяет обновления. Версионирование помогает обеспечить, что старые кэши не будут служить бесконечно:
workbox.routing.registerRoute(
  ({request}) => request.destination === 'image',
  new workbox.strategies.StaleWhileRevalidate({
    cacheName: 'image-cache-v1',
  })
);

Управление устаревшими кэшами

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

self.addEventListener('activate', (event) => {
  const currentCaches = ['js-cache-v2', 'html-cache-v3', 'image-cache-v1'];
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames.map((cacheName) => {
          if (!currentCaches.includes(cacheName)) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Интеграция с Workbox Build

При сборке проекта Workbox позволяет автоматически генерировать манифест с версиями кэшей. Использование injectManifest или generateSW учитывает хэширование файлов:

workbox-build.injectManifest({
  swSrc: 'src/sw-template.js',
  swDest: 'dist/sw.js',
  globDirectory: 'dist',
  globPatterns: ['**/*.{js,css,html,png,jpg}'],
});

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

Рекомендации по версионированию

  • Использовать семантическое версионирование (v1, v2, v3) для основных кэшей.
  • Разделять кэши по типам ресурсов: скрипты, стили, изображения, данные API.
  • Автоматизировать процесс через инструменты сборки и хэширование файлов, чтобы минимизировать ручное управление версиями.
  • Проверять стратегию кэширования для каждого ресурса и комбинировать с версионированием, чтобы избегать загрузки устаревших данных.

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