Workbox — это мощная библиотека для работы с Service Worker в JavaScript, упрощающая реализацию стратегий кэширования и оптимизацию офлайн-доступа. В основе работы лежит предопределённый набор стратегий кэширования, которые позволяют гибко управлять сохранением ресурсов, временем их жизни и обновлением.
Workbox предоставляет несколько ключевых стратегий кэширования:
CacheFirst Предпочитает данные из кэша. Если ресурс отсутствует, происходит запрос к сети. Используется для статических ресурсов, таких как изображения, CSS и JS.
workbox.routing.registerRoute(
({request}) => request.destination === 'image',
new workbox.strategies.CacheFirst({
cacheName: 'images-cache',
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 дней
}),
],
})
);NetworkFirst Сначала пытается получить ресурс с сети, при неудаче использует кэш. Подходит для динамического контента, например, API-запросов.
workbox.routing.registerRoute(
({url}) => url.pathname.startsWith('/api/'),
new workbox.strategies.NetworkFirst({
cacheName: 'api-cache',
networkTimeoutSeconds: 3,
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 5 * 60, // 5 минут
}),
],
})
);StaleWhileRevalidate Возвращает ресурс из кэша мгновенно и параллельно обновляет его с сети. Идеален для часто изменяющихся, но не критичных данных.
workbox.routing.registerRoute(
({request}) => request.destination === 'script',
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'js-cache',
})
);Workbox позволяет устанавливать заголовки для контроля кэширования и безопасности:
Cache-Control — ключевой заголовок для управления временем жизни ресурса. Пример для работы с API:
workbox.routing.registerRoute(
'/api/data',
async ({event}) => {
const response = await fetch(event.request);
const modifiedResponse = new Response(response.body, {
...response,
headers: {
...response.headers,
'Cache-Control': 'no-store, no-cache, must-revalidate',
},
});
return modifiedResponse;
}
);Expires и ETag — используются для валидации кэшированных ресурсов, предотвращая лишние запросы.
Workbox поддерживает интеграцию с заголовками безопасности, которые критичны для современных веб-приложений:
Content-Security-Policy (CSP) Ограничивает источники ресурсов, предотвращая внедрение вредоносного кода:
workbox.routing.registerRoute(
({request}) => request.destination === 'script',
async ({event}) => {
const response = await fetch(event.request);
return new Response(response.body, {
...response,
headers: {
...response.headers,
'Content-Security-Policy': "default-src 'self'; script-src 'self'",
},
});
}
);Strict-Transport-Security (HSTS) Принуждает браузеры использовать HTTPS:
workbox.routing.registerRoute(
({request}) => request.url.startsWith('https://'),
async ({event}) => {
const response = await fetch(event.request);
return new Response(response.body, {
...response,
headers: {
...response.headers,
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
},
});
}
);X-Content-Type-Options Предотвращает MIME-type sniffing:
workbox.routing.registerRoute(
({request}) => request.destination === 'style',
async ({event}) => {
const response = await fetch(event.request);
return new Response(response.body, {
...response,
headers: {
...response.headers,
'X-Content-Type-Options': 'nosniff',
},
});
}
);Workbox включает ряд плагинов, которые расширяют возможности управления кэшем и безопасности:
Кэширование с Workbox не только ускоряет загрузку страниц, но и обеспечивает стабильную работу приложения офлайн. Для максимальной эффективности важно:
// Кэшируем статические файлы с CacheFirst и ExpirationPlugin
workbox.routing.registerRoute(
({request}) => ['script', 'style', 'image'].includes(request.destination),
new workbox.strategies.CacheFirst({
cacheName: 'static-resources',
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 100,
maxAgeSeconds: 7 * 24 * 60 * 60,
}),
new workbox.cacheableResponse.CacheableResponsePlugin({
statuses: [0, 200],
}),
],
})
);
// Защищаем API-запросы с NetworkFirst и заголовками
workbox.routing.registerRoute(
({url}) => url.pathname.startsWith('/api/'),
new workbox.strategies.NetworkFirst({
cacheName: 'api-cache',
networkTimeoutSeconds: 5,
plugins: [
new workbox.expiration.ExpirationPlugin({ maxEntries: 50 }),
{
fetchDidSucceed: async ({response}) => {
const modifiedHeaders = new Headers(response.headers);
modifiedHeaders.set('Cache-Control', 'no-store');
modifiedHeaders.set('Strict-Transport-Security', 'max-age=31536000');
return new Response(response.body, { headers: modifiedHeaders });
},
},
],
})
);
Эта конфигурация сочетает кэширование с политиками безопасности, обеспечивая высокую производительность и защиту веб-приложения.