Что такое Service Worker и чем он отличается от обычного JS
Обычный JavaScript выполняется в главном потоке страницы и имеет доступ к DOM. Service Worker работает в отдельном фоновом потоке — у него нет доступа к DOM, но есть возможность перехватывать все сетевые запросы и управлять кэшем браузера.
Жизненный цикл Service Worker:
- Регистрация — страница регистрирует SW через
navigator.serviceWorker.register('/sw.js') - Установка — SW устанавливается и может заранее кэшировать статические ресурсы
- Активация — SW берёт управление над страницей
- Работа — перехватывает запросы через
fetchevent
// sw.js — базовый пример стратегии "cache first"
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(cached => {
return cached || fetch(event.request);
})
);
});
Стратегии кэширования
Service Worker позволяет реализовать разные стратегии для разных типов ресурсов:
| Стратегия | Логика | Применение |
|---|---|---|
| Cache First | Сначала кэш, потом сеть | Статика (CSS, JS, шрифты) |
| Network First | Сначала сеть, при ошибке — кэш | HTML-страницы, данные |
| Stale While Revalidate | Возвращает кэш, фоново обновляет | Изображения, полустатика |
| Network Only | Всегда сеть, без кэша | API персонализации, корзина |
| Cache Only | Только кэш | Офлайн-fallback |
Service Worker и персонализация: подводные камни
Для e-commerce с персонализацией Service Worker создаёт специфический риск: кэшированный персонализированный ответ. Если API рекомендаций попал в кэш SW с долгим TTL — другой пользователь или следующая сессия получит чужие рекомендации.
Правила для персонализированных данных:
- Исключить из кэша все запросы с
AuthorizationилиuserIdпараметрами - Network Only стратегия для API рекомендаций, корзины, профиля
- Cache Only — только для полностью статических ресурсов
// Пример: исключаем API персонализации из кэширования
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname.startsWith('/api/personalization/')) {
// Всегда через сеть — не кэшировать
event.respondWith(fetch(event.request));
return;
}
// Остальные ресурсы — cache first
event.respondWith(cacheFirst(event.request));
});
Применение в e-commerce PWA
- Офлайн-страница — пользователь без интернета видит кастомную страницу, а не ошибку браузера
- Предзагрузка — SW загружает ресурсы следующей страницы пока пользователь читает текущую
- Web Push — уведомления о брошенной корзине, снижении цены, новинках
- Background sync — добавление в список желаний без интернета с синхронизацией при восстановлении связи
Важно: при обновлении сайта (деплой) нужно инвалидировать кэш Service Worker. Пользователи могут продолжать видеть устаревшую версию, пока SW не обновится. Используйте версионированные cache key или вызов
skipWaiting()при критичных обновлениях.