Service Worker - скрипт, який браузер запускає у фоні між сторінкою й мережею. Він перехоплює запити сторінок свого сайту й вирішує, що відповісти: з мережі, з кешу чи згенерувати відповідь сам. На ньому будуються офлайн-режим, PWA, push-сповіщення, фонова синхронізація.
// реєстрація на сторінці
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
// sw.js
const CACHE = 'static-v3';
self.addEventListener('install', (event) => {
event.waitUntil(caches.open(CACHE).then((cache) => cache.addAll(['/offline.html'])));
});
self.addEventListener('fetch', (event) => {
if (event.request.mode === 'navigate') {
event.respondWith(fetch(event.request).catch(() => caches.match('/offline.html')));
}
});
Життєвий цикл:
- install - підготовка: завантажити й закешувати потрібні файли;
- waiting - новий воркер чекає, доки закриються всі вкладки зі старим. Це захищає від ситуації, коли одна сторінка працює зі старими файлами, а запити обслуговує новий воркер;
- activate - новий воркер бере керування; тут видаляють старі кеші;
- fetch - перехоплення запитів.
self.skipWaiting() і clients.claim() прискорюють перемикання, але ціною можливої невідповідності версій.
Стратегії кешування:
- cache first - для хешованих статичних файлів, що не змінюються;
- network first - для HTML і API: свіже, а кеш лише як запас при відсутності мережі;
- stale-while-revalidate - миттєво з кешу, паралельно оновити кеш з мережі.
Бібліотека Workbox реалізує ці стратегії й генерує воркер під час збирання (у Vite - vite-plugin-pwa).
Чим небезпечна помилка:
- воркер живе довше за сторінку. Він встановлений у браузері користувача й перехоплює запити навіть після того, як ви виправили сайт. Якщо воркер помилково кешує HTML «назавжди», користувачі бачитимуть стару версію сайту, і деплой цього не виправить;
- оновлення самого воркера - браузер перевіряє, чи змінився
sw.js, при навігації на сайт (за замовчуванням в обхід HTTP-кешу, і щонайменше раз на 24 години). URLsw.jsмає лишатися незмінним: якщо перейменувати файл, старий воркер про новий так і не дізнається; - план відступу: заздалегідь мати «вимикач» - новий
sw.js, що видаляє кеші й знімає реєстрацію (self.registration.unregister()).
Обмеження: лише HTTPS (виняток - localhost), без доступу до DOM, область дії (scope) - каталог, з якого віддано скрипт, і нижче.
Для звичайного сайту (не PWA) Service Worker часто зайвий: HTTP-кешування з хешованими іменами файлів дає більшу частину вигоди без ризиків.