Workbox — это библиотека, упрощающая работу с Service Worker в веб-приложениях. Один из ключевых аспектов работы с Service Worker — управление жизненным циклом и обновлениями. Понимание этих процессов необходимо для обеспечения корректного кэширования ресурсов и обновления контента на стороне клиента.
Service Worker проходит несколько этапов жизненного цикла:
Регистрация Service Worker регистрируется с
помощью метода navigator.serviceWorker.register(). На этом
этапе браузер загружает скрипт Service Worker и создаёт новую сущность,
но ещё не активирует её.
Установка (install) При первом
попадании на страницу или при обновлении Service Worker переходит в
состояние install. В этом событии обычно выполняется
предзагрузка ресурсов в кэш:
self.addEventListener('install', event => {
event.waitUntil(
caches.open('static-v1').then(cache => cache.addAll([
'/index.html',
'/styles.css',
'/app.js'
]))
);
});
Workbox упрощает эту задачу через стратегию precaching:
import { precacheAndRoute } from 'workbox-precaching';
precacheAndRoute(self.__WB_MANIFEST);
Важный момент: до завершения установки Service Worker не считается готовым к активации. Если предзагрузка ресурсов завершается с ошибкой, установка откатывается.
Активация (activate) После успешной
установки Service Worker переходит в состояние activate. На
этом этапе можно управлять старыми кэшами и удалять устаревшие
данные:
self.addEventListener('activate', event => {
const cacheWhitelist = ['static-v1'];
event.waitUntil(
caches.keys().then(cacheNames =>
Promise.all(
cacheNames.map(cacheName => {
if (!cacheWhitelist.includes(cacheName)) {
return caches.delete(cacheName);
}
})
)
)
);
});Рабочее состояние (running) После
активации Service Worker начинает перехватывать сетевые запросы,
обрабатывать push-уведомления и управлять фоновыми
синхронизациями.
При изменении скрипта Service Worker браузер обнаруживает новую версию и запускает процесс обновления:
Загрузка новой версии Браузер загружает новый скрипт и создаёт новый экземпляр Service Worker.
Установка новой версии Новый Service Worker
проходит установку (install), но не активируется
автоматически, если старый Service Worker всё ещё управляет
страницами.
Ожидание активации (waiting) Новый
Service Worker остаётся в состоянии waiting до тех пор,
пока все открытые страницы не будут закрыты или пока не будет вызван
метод skipWaiting.
skipWaitingМетод skipWaiting позволяет новому Service Worker
немедленно перейти в состояние активации, минуя ожидание закрытия всех
страниц:
self.addEventListener('install', event => {
self.skipWaiting();
});
Особенности и риски:
clients.claim(): чтобы
новый Service Worker начал управлять существующими клиентами сразу после
активации, используется метод clients.claim():self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim());
});
Это гарантирует, что все страницы сразу используют новый Service Worker и обновлённые кэши.
Workbox предоставляет встроенные утилиты для управления обновлениями:
skipWaiting(): вызывается из скрипта
Service Worker Workbox для немедленной активации:import { skipWaiting, clientsClaim } from 'workbox-core';
skipWaiting();
clientsClaim();
precacheAndRoute Workbox автоматически отслеживает
изменения файлов, указанных в манифесте, и создаёт новую версию Service
Worker. В сочетании с skipWaiting это обеспечивает быстрое
обновление контента для пользователей.skipWaiting только при уверенности, что
мгновенная активация не нарушит работу текущих страниц.clients.claim() после активации, чтобы
новый Service Worker начал управлять всеми клиентами.waiting и activate может немного
отличаться.Эти механизмы жизненного цикла и обновления позволяют реализовать гибкое и безопасное управление контентом, минимизируя задержки при доставке новых версий приложений и обеспечивая консистентность кэшируемых данных.