Переход с sw-precache на Workbox

Библиотека sw-precache используется для автоматической генерации Service Worker, который кэширует статические ресурсы веб-приложения. Основной принцип работы заключается в анализе файловой структуры проекта и создании манифеста кэшируемых файлов с указанием хэшей, что позволяет реализовать стратегию “cache-first” для улучшения производительности и оффлайн-доступа.

Ключевые элементы конфигурации sw-precache:

  • staticFileGlobs — массив путей к файлам, которые должны быть кэшированы.
  • stripPrefix — удаляет указанный префикс из пути при добавлении в кэш.
  • runtimeCaching — позволяет задать правила динамического кэширования для сетевых запросов, например, API или изображений.
  • navigateFallback — указывает HTML-файл, который будет возвращён при навигации, когда ресурс не найден в кэше.

Пример конфигурации:

const swPrecache = require('sw-precache');

swPrecache.write('service-worker.js', {
  staticFileGlobs: [
    'dist/**/*.html',
    'dist/**/*.css',
    'dist/**/*.js',
    'dist/images/**/*.{png,jpg,gif}'
  ],
  stripPrefix: 'dist/',
  runtimeCaching: [{
    urlPattern: /\/api\/.*$/,
    handler: 'networkFirst'
  }],
  navigateFallback: '/index.html'
});

Ограничения sw-precache

  • Отсутствие поддержки современных стратегий кэширования, таких как stale-while-revalidate и приоритизация запросов.
  • Невозможность использования модульного подхода для кэширования отдельных маршрутов с гибкими условиями.
  • Ограниченные возможности интеграции с инструментами сборки нового поколения, такими как Webpack и Rollup, что усложняет автоматизацию.
  • Поддержка только базовой версии Service Worker API, без возможности работать с push-уведомлениями и background sync.

Преимущества перехода на Workbox

Workbox представляет собой набор модулей для генерации и управления Service Worker, предоставляющий более гибкий и расширяемый подход:

  • Гибкая стратегия кэширования: cache-first, network-first, stale-while-revalidate, network-only, cache-only.
  • Модульная структура: отдельные пакеты для precaching, routing, strategies и background sync.
  • Интеграция с сборщиками: нативная поддержка Webpack через workbox-webpack-plugin.
  • Автоматическое управление версиями кэша: предотвращает устаревание данных без ручного обновления хэшей.
  • Дополнительные функции: фоновые синхронизации, push-уведомления, быстрые fallback-страницы.

Миграция precache

Sw-precache создаёт манифест для предзагрузки файлов. Workbox заменяет его через workbox-build или workbox-webpack-plugin, где можно настроить аналогичный precache:

const { generateSW } = require('workbox-build');

generateSW({
  globDirectory: 'dist',
  globPatterns: [
    '**/*.{html,js,css,png,jpg,gif}'
  ],
  swDest: 'dist/service-worker.js',
  runtimeCaching: [{
    urlPattern: /\/api\/.*$/,
    handler: 'NetworkFirst'
  }],
  navigateFallback: '/index.html',
});

Ключевые отличия:

  • globDirectory заменяет stripPrefix и staticFileGlobs.
  • Стратегии кэширования (handler) имеют более читаемые имена и расширенные возможности.
  • Workbox автоматически генерирует версии кэша на основе хэшей файлов, что исключает коллизии.

Переход на модульную архитектуру

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

  • Создавать обработчики для отдельных URL-шаблонов.
  • Назначать стратегии кэширования для разных типов ресурсов.
  • Обрабатывать fallback-страницы и ошибки сети через кастомные обработчики.

Пример маршрутизации:

import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';

registerRoute(
  ({ request }) => request.destination === 'image',
  new StaleWhileRevalidate({
    cacheName: 'images-cache',
  })
);

Управление версиями и обновлениями

Workbox автоматически обновляет Service Worker при изменении файлов в precache. Для интеграции с пользователем можно использовать события:

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

Это позволяет мгновенно активировать новый Service Worker и обновить кэш без вмешательства пользователя.

Динамическое кэширование

Sw-precache поддерживает только базовые runtimeCaching правила. Workbox расширяет это:

  • Stale-while-revalidate — отдаёт старую версию из кэша, параллельно обновляя её.
  • Network-first — сначала обращается к сети, если не доступно — использует кэш.
  • Cache-only и Network-only — полностью статические или динамические сценарии.

Пример:

import { registerRoute } from 'workbox-routing';
import { NetworkFirst, CacheFirst } from 'workbox-strategies';

registerRoute(
  ({ url }) => url.pathname.startsWith('/api/'),
  new NetworkFirst({
    cacheName: 'api-cache',
    networkTimeoutSeconds: 3,
  })
);

registerRoute(
  ({ request }) => request.destination === 'script',
  new CacheFirst({
    cacheName: 'js-cache',
  })
);

Итоговая структура проекта

Переход с sw-precache на Workbox подразумевает:

  1. Удаление генерации service-worker.js через sw-precache.
  2. Установка workbox-build или workbox-webpack-plugin.
  3. Настройка precache через globDirectory и globPatterns.
  4. Импорт модулей Routing и Strategies для управления динамическим кэшированием.
  5. Использование событий Service Worker для управления обновлениями и fallback.

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