Инвалидация кэша — ключевой аспект при работе с Service Worker и библиотекой Workbox. Она определяет, как обновления ресурсов будут попадать пользователю и как долго устаревшие данные остаются доступными. Правильное управление кэшом позволяет избегать проблем с устаревшей информацией, повышает производительность приложения и улучшает пользовательский опыт.
Workbox поддерживает несколько стратегий обновления ресурсов, каждая из которых решает разные задачи:
Cache First (кэш прежде всего) Этот подход сначала ищет ресурс в кэше, а если его нет — обращается к сети. Используется для статических ресурсов, которые редко изменяются (например, изображения, шрифты).
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
import {ExpirationPlugin} from 'workbox-expiration';
registerRoute(
({request}) => request.destination === 'image',
new CacheFirst({
cacheName: 'images-cache',
plugins: [
new CacheableResponsePlugin({statuses: [0, 200]}),
new ExpirationPlugin({maxEntries: 50, maxAgeSeconds: 30 * 24 * 60 * 60}) // 30 дней
]
})
);
Ключевые моменты:
ExpirationPlugin контролирует время жизни и количество
кэшированных объектов.maxAgeSeconds и maxEntries.Network First (сеть прежде всего) Используется для ресурсов, которые часто обновляются (API-запросы, данные в реальном времени). Сначала запрашивается сеть, а при сбое используется кэш.
import {NetworkFirst} from 'workbox-strategies';
registerRoute(
({url}) => url.pathname.startsWith('/api/'),
new NetworkFirst({
cacheName: 'api-cache',
plugins: [
new CacheableResponsePlugin({statuses: [0, 200]}),
new ExpirationPlugin({maxEntries: 100, maxAgeSeconds: 5 * 60}) // 5 минут
]
})
);
Ключевые моменты:
Stale While Revalidate (устаревший, пока обновляется) Позволяет использовать кэшированную версию мгновенно, одновременно обновляя ресурс в фоне. Подходит для ресурсов, где небольшая задержка актуализации допустима.
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(
({request}) => request.destination === 'script' || request.destination === 'style',
new StaleWhileRevalidate({
cacheName: 'static-resources',
plugins: [
new CacheableResponsePlugin({statuses: [0, 200]})
]
})
);
Ключевые моменты:
Для правильной инвалидации часто используют версии кэша, что позволяет явно обновлять устаревшие данные:
const CACHE_VERSION = 'v2';
const STATIC_CACHE = `static-cache-${CACHE_VERSION}`;
self.addEventListener('install', event => {
event.waitUntil(
caches.open(STATIC_CACHE).then(cache => cache.addAll([
'/index.html',
'/styles.css',
'/main.js'
]))
);
});
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(
keys.filter(key => key !== STATIC_CACHE)
.map(key => caches.delete(key))
)
)
);
});
Особенности подхода:
activate.Workbox Expiration PluginExpirationPlugin позволяет автоматически очищать
устаревший кэш по количеству элементов или времени жизни:
import {ExpirationPlugin} from 'workbox-expiration';
new CacheFirst({
cacheName: 'dynamic-cache',
plugins: [
new ExpirationPlugin({
maxEntries: 100,
maxAgeSeconds: 24 * 60 * 60 // 1 день
})
]
});
Важно помнить:
maxEntries защищает от переполнения кэша.maxAgeSeconds гарантирует, что устаревшие ресурсы будут
удалены, а свежие — загружены заново.Для файлов с уникальным именем или хешем (например,
main.abc123.js) Workbox позволяет обходиться без явной
версии кэша, так как изменение имени файла автоматически приводит к
новому кэшированию. Это особенно удобно для сборки проектов с Webpack
или Vite:
registerRoute(
({request}) => request.destination === 'script',
new CacheFirst({
cacheName: 'js-cache',
plugins: [
new CacheableResponsePlugin({statuses: [0, 200]})
]
})
);
Преимущества хеширования:
Для API и других часто обновляемых ресурсов рекомендуется использовать комбинацию стратегий:
Network First для критичных данных.Stale While Revalidate для не критичных, но требующих
быстрой загрузки.ExpirationPlugin.Эта комбинация позволяет балансировать между скоростью, актуальностью и размером кэша.
Эти подходы позволяют выстроить устойчивую и предсказуемую систему кэширования, обеспечивающую актуальность данных и минимальное время отклика для пользователей.