Service Worker — это отдельный скрипт, который браузер запускает в фоновом режиме, отделённо от веб-страницы. Он способен перехватывать сетевые запросы, управлять кэшированием ресурсов и обеспечивать работу приложения в оффлайн-режиме. Жизненный цикл Service Worker строго структурирован, что обеспечивает контроль над обновлением и управлением кэшем.
Service Worker проходит несколько ключевых стадий: регистрация, установка, активация и работа с запросами. Каждая из этих стадий имеет свои особенности и API-интерфейсы.
Регистрация выполняется с помощью метода
navigator.serviceWorker.register(). Этот метод принимает
путь к файлу скрипта Service Worker и возвращает промис, который
сигнализирует об успешной регистрации.
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker зарегистрирован:', registration);
})
.catch(error => {
console.error('Ошибка регистрации Service Worker:', error);
});
}
Ключевые моменты:
localhost.На этапе установки Service Worker может кэшировать необходимые
ресурсы. Событие install позволяет выполнить подготовку к
работе приложения в оффлайн-режиме.
self.addEventListener('install', event => {
event.waitUntil(
caches.open('app-cache-v1')
.then(cache => {
return cache.addAll([
'/',
'/index.html',
'/styles.css',
'/main.js',
'/logo.png'
]);
})
);
});
Важные моменты:
event.waitUntil() гарантирует, что установка
Service Worker не будет завершена до успешного выполнения всех
асинхронных операций.После установки Service Worker переходит в стадию активации. Это событие используется для управления устаревшими кэшами и подготовки нового Service Worker к работе.
self.addEventListener('activate', event => {
const cacheWhitelist = ['app-cache-v1'];
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (!cacheWhitelist.includes(cacheName)) {
return caches.delete(cacheName);
}
})
);
})
);
});
Особенности:
После активации Service Worker может перехватывать сетевые запросы
через событие fetch. Это основной механизм для реализации
оффлайн-режима и стратегий кэширования.
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
return response || fetch(event.request);
})
);
});
Принципы работы:
caches.match() проверяет наличие запрашиваемого ресурса
в кэше.fetch().Обновление Service Worker происходит, когда браузер обнаруживает изменения в скрипте при регистрации. Новый Service Worker устанавливается, но не активируется до закрытия всех контролируемых страниц. Это предотвращает внезапные изменения поведения приложения.
Стратегии обновления:
self.skipWaiting().clients.claim().self.addEventListener('install', event => {
self.skipWaiting();
});
self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim());
});
Библиотека sw-precache автоматизирует генерацию
Service Worker с заранее закэшированными файлами. Она анализирует проект
и создаёт список ресурсов, который затем используется в событии
install.
Пример конфигурации sw-precache:
const swPrecache = require('sw-precache');
swPrecache.write('sw.js', {
staticFileGlobs: [
'index.html',
'styles/**/*.css',
'scripts/**/*.js',
'images/**/*.{png,jpg,gif,svg}'
],
stripPrefix: '',
runtimeCaching: [{
urlPattern: /\/api\//,
handler: 'networkFirst'
}]
});
Основные возможности:
staticFileGlobs.Жизненный цикл Service Worker обеспечивает предсказуемое поведение приложения, позволяя контролировать установку, активацию, обработку запросов и обновления кэша. Sw-precache облегчает работу с кэшированием, автоматизируя генерацию Service Worker и минимизируя ошибки ручного управления ресурсами.