Workbox предоставляет мощные инструменты для управления кэшированием и обновлениями сервис-воркеров, включая возможность отслеживания появления новых версий приложения на стороне клиента. Контроль за обновлениями позволяет реализовать сценарии «мягкого» обновления, уведомления пользователя о доступных обновлениях и автоматическое применение новых ресурсов.
Для начала необходимо корректно зарегистрировать сервис-воркер с использованием Workbox. Пример регистрации с обработкой событий обновления:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then(registration => {
// Проверка наличия нового сервис-воркера
registration.onupdatefo und = () => {
const newWorker = registration.installing;
newWorker.onstatecha nge = () => {
if (newWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
console.log('Доступна новая версия приложения');
} else {
console.log('Контент кэширован впервые');
}
}
};
};
}).catch(error => {
console.error('Ошибка при регистрации сервис-воркера:', error);
});
});
}
В этом коде важно различать состояния installed и
наличие navigator.serviceWorker.controller. Если контроллер
уже существует, это означает, что в браузере есть активная версия
приложения, и новая версия была установлена, но еще не активирована.
Workbox позволяет сервис-воркеру отправлять сообщения клиенту. Для
этого используется метод postMessage в воркере и
navigator.serviceWorker.addEventListener('message', ...) на
клиенте.
Пример отправки сообщения из сервис-воркера при обновлении:
self.addEventListener('install', event => {
self.skipWaiting();
});
self.addEventListener('activate', event => {
event.waitUntil(
clients.claim().then(() => {
self.clients.matchAll().then(clients => {
clients.forEach(client => client.postMessage({ type: 'NEW_VERSION_AVAILABLE' }));
});
})
);
});
На стороне клиента прослушивание сообщений выглядит так:
navigator.serviceWorker.addEventListener('message', event => {
if (event.data && event.data.type === 'NEW_VERSION_AVAILABLE') {
console.log('Обнаружена новая версия приложения');
// Можно инициировать уведомление или автоматическое обновление
}
});
Для немедленного применения новой версии можно использовать метод
skipWaiting() в сервис-воркере и команду
clients.claim() при активации. Однако необходимо
контролировать момент, когда это произойдет, чтобы не нарушить текущую
сессию пользователя. Обычно применяется комбинация:
function promptUserToUpdate(registration) {
if (confirm("Доступна новая версия приложения. Обновить сейчас?")) {
if (registration.waiting) {
registration.waiting.postMessage({ type: 'SKIP_WAITING' });
}
}
}
navigator.serviceWorker.addEventListener('controllerchange', () => {
window.location.reload();
});
В сервис-воркере:
self.addEventListener('message', event => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
Workbox предоставляет события жизненного цикла для стратегий
кэширования, которые можно использовать для отслеживания прогресса
обновления отдельных ресурсов. Например, с использованием
Workbox.precaching:
import { precacheAndRoute, precache } from 'workbox-precaching';
precacheAndRoute(self.__WB_MANIFEST);
self.addEventListener('message', event => {
if (event.data && event.data.type === 'CHECK_UPDATES') {
precache.getCacheKeys().then(keys => {
console.log('Кэшированные ресурсы:', keys);
});
}
});
Используя precacheAndRoute, можно контролировать
установку, активацию и проверку обновлений для конкретных файлов
манифеста. Это особенно важно для крупных приложений, где кэширование
каждого ресурса имеет значение для корректного обновления.
installing, installed,
activating, activated) помогает
диагностировать проблемы с кэшированием и обновлениями.NetworkFirst для данных и
CacheFirst для статических ресурсов) минимизирует задержки
при обновлении контента.Комбинирование отслеживания состояния сервис-воркера, прослушивания сообщений и уведомления пользователя позволяет реализовать гибкую систему обновления, которая:
Эта модель является стандартом для современных PWA и полностью интегрируется с возможностями Workbox по управлению кэшом и жизненным циклом сервис-воркера.