Workbox — это мощная библиотека для упрощения создания сервис-воркеров и реализации стратегий кэширования в веб-приложениях. При работе с современными UI-фреймворками, такими как React, Vue или Angular, её возможности позволяют повысить производительность и улучшить оффлайн-опыт пользователей без значительных изменений структуры проекта.
Сервис-воркер как отдельный модуль
В большинстве UI-фреймворков рекомендуется держать сервис-воркер отдельно от основной логики приложения. Это позволяет:
workbox-core,
workbox-routing, workbox-strategies) в
модульной структуре.Пример подключения сервис-воркера в проекте на React:
// service-worker.js
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';
precacheAndRoute(self.__WB_MANIFEST);
registerRoute(
({ request }) => request.destination === 'script' || request.destination === 'style',
new StaleWhileRevalidate()
);
После этого сервис-воркер регистрируется в точке входа приложения:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js');
});
}UI-фреймворки активно используют модульную структуру с компонентами. Для улучшения производительности важно кэшировать не только статические файлы, но и ресурсы, используемые компонентами, такие как:
Workbox предоставляет несколько стратегий кэширования, наиболее часто применяемых в контексте UI-фреймворков:
Пример кэширования изображений в Vue-приложении:
registerRoute(
({ request }) => request.destination === 'image',
new CacheFirst({
cacheName: 'images-cache',
plugins: [
new ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 дней
}),
],
})
);
Современные SPA используют роутеры (React Router, Vue Router, Angular Router). Workbox позволяет обрабатывать навигационные запросы и отдавать основной HTML для оффлайн-доступа, обеспечивая корректный переход между страницами.
Пример для React Router:
registerRoute(
({ request }) => request.mode === 'navigate',
new NetworkFirst({
cacheName: 'html-cache',
})
);
Это гарантирует, что все маршруты приложения смогут работать оффлайн, возвращая последний кэшированный HTML.
UI-фреймворки часто пересобирают бандлы при каждой сборке. Для предотвращения проблем с устаревшими файлами нужно использовать превентивное управление кэшем:
precacheAndRoute автоматически интегрируется с
манифестом сборки, что позволяет сервис-воркеру обновлять кэш при
изменении хешей файлов.BroadcastUpdatePlugin уведомляет
приложение о наличии новых версий ресурсов.Пример уведомления в Angular:
import { BroadcastUpdatePlugin } from 'workbox-broadcast-update';
registerRoute(
({ request }) => request.destination === 'script',
new StaleWhileRevalidate({
plugins: [new BroadcastUpdatePlugin()],
})
);
navigator.serviceWorker.addEventListener('message', (event) => {
if (event.data.type === 'CACHE_UPDATED') {
console.log('Обновлённый ресурс:', event.data.updatedURL);
}
});
workbox-webpack-plugin или
vite-plugin-workbox, чтобы автоматически генерировать
манифест для precache.ngsw-config.json.workbox-routing, workbox-strategies)
для уменьшения размера бандла.ExpirationPlugin.Некоторые UI-фреймворки используют глобальные состояния (Redux, Vuex, NgRx). Workbox позволяет кэшировать API-запросы, данные которых обновляют состояние:
NetworkFirst с fallback на
кэш.Пример для Redux:
registerRoute(
({ url }) => url.pathname.startsWith('/api/data'),
new NetworkFirst({
cacheName: 'api-data-cache',
plugins: [
{
cacheDidUpdate: async ({ cacheName, request }) => {
const response = await caches.match(request);
const data = await response.json();
store.dispatch({ type: 'UPDATE_DATA', payload: data });
},
},
],
})
);