Что такое Service Workers в JavaScript?
Что такое Service Workers
Service Worker — это тип Web Worker, который браузер регистрирует и запускает в отдельном потоке, независимом от основного потока JavaScript и DOM. Он выступает посредником (proxy) между веб-приложением, браузером и сетью, перехватывая и обрабатывая сетевые запросы.
Ключевые особенности
- Нет доступа к DOM — Service Worker не может напрямую взаимодействовать со страницей; общение идёт через
postMessage. - Работает в HTTPS — по соображениям безопасности Service Workers доступны только на защищённых соединениях (или
localhost). - Управляет жизненным циклом самостоятельно — браузер может «спящий» SW завершить и поднять снова по необходимости.
- Событийно-ориентированный — реагирует на события
install,activate,fetch,push,sync.
Жизненный цикл
Регистрация → Installing → Waiting → Activating → Activated → Redundant
- Installing — SW устанавливается, здесь кешируют статику (
cache.addAll). - Waiting — новая версия ждёт, пока старая перестанет контролировать клиентов.
- Activating — SW берёт управление; здесь чистят устаревший кеш.
- Activated — SW перехватывает
fetch-запросы клиентов.
Стратегии кеширования
Cache First (офлайн-приоритет)
Возвращает ресурс из кеша, при отсутствии — идёт в сеть. Подходит для статических ассетов.
Network First (сеть-приоритет)
Сначала пробует сеть, при ошибке — кеш. Подходит для динамического API.
Stale-While-Revalidate
Отдаёт кешированный ответ немедленно, фоново обновляет кеш из сети.
Пример регистрации и перехвата запросов
// Регистрация SW в основном коде приложения
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/sw.js')
.then(reg => console.log('SW зарегистрирован:', reg.scope))
.catch(err => console.error('Ошибка регистрации SW:', err));
}
// sw.js — файл Service Worker
const CACHE_NAME = 'app-cache-v1';
const STATIC_ASSETS = ['/index.html', '/main.js', '/styles.css'];
// Установка: кешируем статику
self.addEventListener('install', (event: ExtendableEvent) => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(STATIC_ASSETS))
);
});
// Активация: удаляем старые кеши
self.addEventListener('activate', (event: ExtendableEvent) => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k)))
)
);
});
// Перехват запросов: стратегия Cache First
self.addEventListener('fetch', (event: FetchEvent) => {
event.respondWith(
caches.match(event.request).then(cached => {
// Возвращаем кешированный ответ или идём в сеть
return cached ?? fetch(event.request);
})
);
});
Применение в PWA
- Офлайн-режим — приложение работает без сети благодаря кешированным ресурсам.
- Push-уведомления — SW принимает
push-события от сервера и показывает нотификации. - Background Sync — откладывает запросы до восстановления сети.
- Ускорение загрузки — статика отдаётся из кеша мгновенно, без сети.
Что хочет услышать интервьюер
Понимание того, что SW работает в отдельном потоке без доступа к DOM
Знание жизненного цикла: install → activate → fetch и роли каждого этапа
Умение объяснить хотя бы одну стратегию кеширования (Cache First, Network First, Stale-While-Revalidate)
Понимание ограничений: только HTTPS, асинхронная природа, отсутствие DOM
Понимание практической роли SW в контексте PWA: офлайн, push, background sync
Пример: Регистрация Service Worker
// Регистрация Service Worker в приложении
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/sw.js', { scope: '/' })
.then(registration => {
console.log('SW активен, scope:', registration.scope);
})
.catch(error => {
console.error('Регистрация SW провалилась:', error);
});
});
}
Пример: Стратегия Stale-While-Revalidate
// sw.js — стратегия Stale-While-Revalidate
const CACHE = 'dynamic-v1';
self.addEventListener('fetch', (event: FetchEvent) => {
event.respondWith(
caches.open(CACHE).then(async cache => {
const cached = await cache.match(event.request);
// Фоново обновляем кеш из сети
const networkFetch = fetch(event.request).then(response => {
cache.put(event.request, response.clone());
return response;
});
// Отдаём кешированный ответ немедленно, иначе ждём сеть
return cached ?? networkFetch;
})
);
});
Типичные ошибки
Путают Service Worker с обычным Web Worker — не понимают разницы в назначении
Не знают, что SW перехватывает только запросы клиентов, которых он контролирует (в своём scope)
Забывают про этап Waiting — не понимают, почему новая версия SW не активируется сразу
Считают, что SW может напрямую обращаться к DOM или переменным основного потока
Не учитывают требование HTTPS и удивляются, почему SW не работает на http://


