Workbox — это набор инструментов для управления кэшированием и стратегиями офлайн-доступа в приложениях на JavaScript. Его ключевая цель — упрощение создания прогрессивных веб-приложений (PWA), где критически важно обеспечить доступность контента даже при отсутствии сетевого подключения.
Первым шагом является регистрация сервис-воркера в основном скрипте приложения:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker зарегистрирован:', registration);
})
.catch(error => {
console.error('Ошибка при регистрации Service Worker:', error);
});
}
Файл sw.js станет точкой управления кэшированием и
стратегиями обработки запросов.
Workbox предоставляет несколько встроенных стратегий, каждая из которых решает определённые задачи UX при офлайн-режиме:
Cache First Предпочтение отдаётся локальному кэшу. Сетевой запрос выполняется только при отсутствии ресурса в кэше. Идеально для статических ресурсов, таких как изображения и шрифты:
import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';
registerRoute(
({request}) => request.destination === 'image',
new CacheFirst({
cacheName: 'images-cache',
plugins: [
new ExpirationPlugin({ maxEntries: 50, maxAgeSeconds: 30 * 24 * 60 * 60 })
]
})
);Network First Сначала выполняется сетевой запрос, кэш используется как резерв. Стратегия подходит для динамического контента, где важна актуальность данных:
import { NetworkFirst } from 'workbox-strategies';
registerRoute(
({request}) => request.destination === 'document',
new NetworkFirst({
cacheName: 'pages-cache',
networkTimeoutSeconds: 3
})
);Stale While Revalidate Возвращает кэшированную версию сразу, а сетевой запрос обновляет кэш в фоне. Отлично подходит для ускорения загрузки страниц и снижения задержек:
import { StaleWhileRevalidate } from 'workbox-strategies';
registerRoute(
({request}) => request.destination === 'script' || request.destination === 'style',
new StaleWhileRevalidate({
cacheName: 'static-resources'
})
);Workbox позволяет заранее кэшировать ключевые ресурсы, чтобы
обеспечить доступ к ним в офлайн-режиме. Это реализуется через
workbox-precaching:
import { precacheAndRoute } from 'workbox-precaching';
precacheAndRoute([
{ url: '/index.html', revision: '1' },
{ url: '/styles/main.css', revision: '1' },
{ url: '/scripts/main.js', revision: '1' }
]);
Примечание: Каждому ресурсу присваивается
revision для контроля обновлений кэша. При изменении файла
revision необходимо увеличивать.
Для обеспечения плавного UX важно обрабатывать ситуации, когда пользователь находится офлайн. Можно создавать fallback-страницы:
registerRoute(
({request}) => request.mode === 'navigate',
async ({event}) => {
try {
return await fetch(event.request);
} catch (error) {
return caches.match('/offline.html');
}
}
);
Такой подход гарантирует, что пользователь увидит информативную страницу даже при отсутствии соединения.
Для динамических данных, получаемых через API, Workbox предлагает
стратегии с комбинированным подходом. Часто используется
NetworkFirst с ограничением времени хранения кэша:
registerRoute(
({url}) => url.pathname.startsWith('/api/'),
new NetworkFirst({
cacheName: 'api-cache',
plugins: [
new ExpirationPlugin({
maxEntries: 100,
maxAgeSeconds: 5 * 60 // 5 минут
})
]
})
);
Такой подход сохраняет свежесть данных при онлайн-доступе и предоставляет доступ к кэшированным результатам при отсутствии сети.
StaleWhileRevalidate для CSS и JS ускоряет отображение
интерфейса.ExpirationPlugin
предотвращает переполнение хранилища и сбои на устройствах с
ограниченной памятью.Workbox легко интегрируется с Webpack через плагин
WorkboxWebpackPlugin. Это позволяет автоматизировать
генерацию сервис-воркеров и управление версионированием ресурсов:
const { GenerateSW } = require('workbox-webpack-plugin');
module.exports = {
plugins: [
new GenerateSW({
clientsClaim: true,
skipWaiting: true,
runtimeCaching: [
{
urlPattern: /\.(?:png|jpg|jpeg|svg|gif)$/,
handler: 'CacheFirst',
options: {
cacheName: 'images',
expiration: { maxEntries: 60, maxAgeSeconds: 30 * 24 * 60 * 60 }
}
}
]
})
]
};
Автоматическая генерация сервис-воркера упрощает поддержку PWA и снижает риск ошибок ручного кэширования.