Service workers are specialized JavaScript assets that act as network proxies between your web application and the server, enabling offline functionality, background processing, and push notifications. They run on a separate thread from your main application code, intercepting network requests to implement sophisticated caching strategies, background sync, and persistent offline experiences. Understanding the service worker lifecycle — registration, installation, activation — and mastering caching patterns like cache-first, network-first, and stale-while-revalidate transforms a standard website into a progressive web app (PWA) that feels instant, works offline, and rivals native applications in user experience. The key mental model: service workers are event-driven workers that wake up to handle specific events (install, activate, fetch, push, sync), then go dormant — they don't run continuously.
What This Cheat Sheet Covers
This topic spans 18 focused tables and 153 indexed concepts. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
Table 1: Service Worker Registration and Lifecycle
Service worker registration establishes the worker's operational scope and initiates the browser's lifecycle state machine: install → waiting → activate → controlling. The lifecycle ensures that new versions of your service worker don't disrupt currently open pages, and understanding state transitions is critical for implementing smooth updates without forcing users to close tabs.
| Method/Event | Example | Description |
|---|---|---|
navigator.serviceWorker .register('/sw.js', { scope: '/' }) .then(reg => console.log(reg.scope)) | • Registers a new service worker with the browser • scope defines which URLs the worker controls (defaults to the worker script's directory). | |
self.addEventListener('install', e => { e.waitUntil(caches.open('v1') .then(cache => cache.addAll(['/'])))}) | • Fires once when a new worker is discovered • ideal for precaching critical assets before the worker activates | |
self.addEventListener('activate', e => { e.waitUntil(clients.claim())}) | • Fires when the worker becomes active • perfect for cleanup tasks like deleting old caches and claiming existing clients | |
self.addEventListener('fetch', e => { e.respondWith(caches.match(e.request) .then(r => r || fetch(e.request)))}) | • Fires on every network request within the worker's scope • lets you intercept and customize responses by serving from cache or network | |
self.addEventListener('install', () => { self.skipWaiting()}) | Forces a waiting worker to activate immediately without waiting for open tabs to close, replacing the currently active worker. |