Отладка проблем с устаревшим кэшем

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

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

  • Версионирование файлов – если имена файлов не меняются при обновлении, сервис-воркер может считать, что кэш актуален.
  • Параметры cacheId и dontCacheBustUrlsMatching – некорректная настройка этих опций может блокировать обновление кэша.
  • Время жизни кэша – старые файлы остаются в кэше, пока сервис-воркер не инициирует их перезапись.

Настройка параметров для контроля кэша

cacheId

cacheId добавляется к имени кэша и помогает различать версии приложения. Изменение cacheId приводит к созданию нового кэша и удалению старого. Пример:

swPrecache.write('service-worker.js', {
  staticFileGlobs: ['dist/**.js', 'dist/**.css'],
  cacheId: 'my-app-v2',
  stripPrefix: 'dist/'
});

В этом примере при смене cacheId с my-app-v1 на my-app-v2 все предыдущие кэши автоматически помечаются как устаревшие.

dontCacheBustUrlsMatching

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

dontCacheBustUrlsMatching: /\.\w{8}\./

Это важно для файлов с хешированными именами (main.abcdef12.js), чтобы не создавать лишние версии кэша при каждом обновлении.

stripPrefix

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

Методы обновления и очистки кэша

Автоматическое обновление

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

  1. Сборка нового сервис-воркера с обновлёнными файлами и параметрами.
  2. Установка нового сервис-воркера браузером.
  3. Активация нового сервис-воркера и удаление старого кэша.

Ручная очистка кэша

Иногда требуется форсированная очистка устаревшего кэша. В сервис-воркере можно добавить обработчик activate:

self.addEventListener('activate', function(event) {
  const expectedCaches = ['my-app-v2'];
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (expectedCaches.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

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

Отладка устаревшего кэша

Инструменты браузера

В Chrome DevTools:

  • Вкладка Application → Cache Storage позволяет видеть все кэши и их содержимое.
  • Опция Update on reload в панели Service Workers гарантирует загрузку нового сервис-воркера при обновлении страницы.

Логирование событий сервис-воркера

Добавление логов помогает отследить поведение кэша:

self.addEventListener('install', function(event) {
  console.log('Service Worker: installing...');
});

self.addEventListener('activate', function(event) {
  console.log('Service Worker: activating...');
});

self.addEventListener('fetch', function(event) {
  console.log('Fetching:', event.request.url);
});

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

Проверка версий кэша

Использование caches.keys() позволяет увидеть, какие кэши активны:

caches.keys().then(function(names) {
  console.log('Current caches:', names);
});

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

Практические советы

  • Всегда хешировать имена статических файлов при сборке приложения, чтобы новые версии автоматически воспринимались сервис-воркером как изменённые.
  • Изменять cacheId при крупных обновлениях, чтобы гарантировать сброс старого кэша.
  • Настраивать dontCacheBustUrlsMatching для файлов с уже встроенными хэшами, чтобы избежать лишнего повторного кэширования.
  • При отладке использовать DevTools и логирование всех событий сервис-воркера.
  • Всегда проверять fetch события и соответствие кэшированных ресурсов реальному содержимому сервера.

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