Частичное обновление precache

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


Принципы работы precache

Precache основывается на манифесте ресурсов, который содержит список URL и их контрольные суммы (hash). Контрольная сумма позволяет сервис-воркеру определить, какие файлы изменились с момента последней активации:

  • Если контрольная сумма файла совпадает с предыдущей версией, файл остаётся в кэше.
  • Если контрольная сумма изменилась, файл перезаписывается в кэше.

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


Настройка частичного обновления

Для включения precache используется пакет workbox-precaching. Основные шаги:

import { precacheAndRoute } from 'workbox-precaching';

// Список ресурсов, который генерируется автоматически (например, с помощью workbox-build)
precacheAndRoute(self.__WB_MANIFEST);

self.__WB_MANIFEST — это массив объектов, содержащих url и revision:

[
  { "url": "/index.html", "revision": "a1b2c3d4" },
  { "url": "/styles/main.css", "revision": "e5f6g7h8" },
  { "url": "/scripts/app.js", "revision": "i9j0k1l2" }
]
  • url — путь к ресурсу
  • revision — хэш или версия ресурса, уникальная для каждого изменения

Если при сборке новый хэш отличается от предыдущего, ресурс будет обновлён в кэше.


Автоматическое сравнение версий

Workbox поддерживает динамическое сравнение ревизий. Когда сервис-воркер активируется, выполняется алгоритм:

  1. Сравниваются текущие ревизии в кэше с ревизиями из манифеста.
  2. Устаревшие ресурсы удаляются.
  3. Загружаются новые или изменённые файлы.
  4. Сохраняются в кэше с новым ревизионным ключом.

Это гарантирует, что старые файлы не остаются в кэше, предотвращая конфликты версий.


Использование skipWaiting и clientsClaim

Для корректного внедрения обновлённых ресурсов в приложение часто применяют:

import { precacheAndRoute } from 'workbox-precaching';
import { clientsClaim } from 'workbox-core';

self.skipWaiting();
clientsClaim();

precacheAndRoute(self.__WB_MANIFEST);
  • self.skipWaiting() заставляет новый сервис-воркер активироваться сразу после установки.
  • clientsClaim() позволяет новому сервис-воркеру контролировать все открытые страницы без необходимости их перезагрузки.

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


Частичное обновление с динамическим добавлением ресурсов

Иногда требуется добавлять ресурсы в precache во время выполнения, без пересборки всего манифеста. Workbox предоставляет метод precache.addToCacheList():

import { precache } from 'workbox-precaching';

precache.addToCacheList([
  { url: '/dynamic-resource.js', revision: 'v1' }
]);

После этого Workbox:

  1. Проверит, есть ли ресурс с указанной ревизией в кэше.
  2. Если нет, загрузит ресурс и сохранит его.
  3. Если есть, пропустит загрузку, что минимизирует сетевой трафик.

Настройка стратегии частичного обновления

Можно управлять поведением обновления файлов через Workbox plugins, например:

  • ExpirationPlugin — контролирует срок жизни кэшированных файлов.
  • CacheableResponsePlugin — задаёт условия для кэширования только успешных ответов.

Пример с ExpirationPlugin для precache:

import { ExpirationPlugin } from 'workbox-expiration';
import { precacheAndRoute } from 'workbox-precaching';

precacheAndRoute(self.__WB_MANIFEST, {
  plugins: [
    new ExpirationPlugin({
      maxEntries: 50,
      maxAgeSeconds: 7 * 24 * 60 * 60, // 1 неделя
    })
  ],
});

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


Логирование изменений

Для отладки частичного обновления полезно включить логирование:

import { setCacheNameDetails } from 'workbox-core';

setCacheNameDetails({
  prefix: 'my-app',
  suffix: 'v1',
  precache: 'precache',
});

self.addEventListener('install', event => {
  console.log('Service Worker install event triggered');
});

self.addEventListener('activate', event => {
  console.log('Service Worker activated');
});

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