Service Worker — это скрипт, который браузер запускает отдельно от веб-страницы, позволяя перехватывать сетевые запросы, управлять кэшем и обеспечивать работу веб-приложений в оффлайн-режиме. Он работает как посредник между веб-приложением и сетью, предоставляя возможность создавать высокопроизводительные и надежные приложения.
Service Worker регистрируется в основном скрипте страницы через
объект navigator.serviceWorker. Ключевой момент —
регистрация должна происходить только на страницах, доступных через
HTTPS, за исключением localhost, где разрешено
тестирование.
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('Service Worker зарегистрирован:', registration);
})
.catch(error => {
console.error('Ошибка регистрации Service Worker:', error);
});
}
Особенности регистрации:
updatefound позволяет отслеживать появление
новой версии.Жизненный цикл Service Worker состоит из нескольких стадий:
Install (установка) На этом этапе создаются кэши
и подготавливаются ресурсы для работы оффлайн. Обработчик события
install обычно используется для предварительного
кэширования статических файлов.
self.addEventListener('install', event => {
event.waitUntil(
caches.open('v1').then(cache => {
return cache.addAll([
'/index.html',
'/styles.css',
'/script.js'
]);
})
);
});Activate (активация) Событие
activate используется для очистки старых кэшей и подготовки
нового Service Worker к управлению страницей.
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys => {
return Promise.all(
keys.filter(key => key !== 'v1')
.map(key => caches.delete(key))
);
})
);
});Fetch (перехват запросов) Service Worker может перехватывать сетевые запросы и возвращать закэшированные данные или выполнять сетевой запрос.
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});Update (обновление) Обновление Service Worker происходит автоматически при обнаружении изменений в скрипте. Новая версия переходит в стадию установки, пока старая еще активна. Переключение происходит после закрытия всех вкладок, использующих старую версию.
Кэширование позволяет ускорить загрузку приложения и обеспечить оффлайн-доступ. Основные стратегии кэширования:
Пример стратегии Cache First:
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
Service Worker поддерживает push-уведомления и фоновую синхронизацию данных. Это позволяет уведомлять пользователя о событиях или обновлениях без активной вкладки.
Пример обработки push-события:
self.addEventListener('push', event => {
const data = event.data.json();
self.registration.showNotification(data.title, {
body: data.body,
icon: '/icon.png'
});
});
Фоновая синхронизация:
self.addEventListener('sync', event => {
if (event.tag === 'sync-data') {
event.waitUntil(syncDataToServer());
}
});
Service Worker имеет ряд ограничений:
postMessage.Безопасность: необходимо избегать хранения конфиденциальных данных в открытых кэших, так как кэш может быть доступен через злоумышленника при XSS-атаках.
Для связи Service Worker и страницы используется метод
postMessage. Это позволяет передавать данные и получать
статус операций, таких как загрузка ресурсов или обработка
синхронизации.
// В Service Worker
self.addEventListener('message', event => {
console.log('Сообщение от клиента:', event.data);
event.source.postMessage('Данные получены');
});
// На странице
navigator.serviceWorker.controller.postMessage('Привет, SW!');
navigator.serviceWorker.addEventListener('message', event => {
console.log('Ответ от SW:', event.data);
});
Service Worker — фундаментальный инструмент для построения прогрессивных веб-приложений (PWA), обеспечивающий оффлайн-доступ, кэширование, уведомления и фоновые процессы. Правильное использование жизненного цикла и стратегий кэширования позволяет создавать быстрые, надежные и удобные веб-приложения.