Service workers are background scripts that run separately from the main browser thread. They sit between your web app and the network, acting like a programmable proxy.
With service workers, you can add powerful capabilities to your web apps such as offline support, caching, background sync, and push notifications, making them feel more like native mobile apps.
They do not have direct access to the DOM but can communicate with pages using the postMessage API.
navigator.serviceWorker.register().localhost for development).To start using a service worker, you first check if the browser supports it and then call the register() method from your main JavaScript file.
In the service worker file (commonly sw.js), you listen for lifecycle events:
install: Good place to open a cache and store essential assets.activate: Used for cleaning up old caches and getting the worker ready.fetch: Allows you to intercept network requests and serve cached responses.Because service workers are event-driven, the browser starts them when needed and stops them when idle, saving memory and battery.
Registration is done from your main JavaScript file (for example, app.js or inside a script tag in your HTML).
// Check if the browser supports service workers
if ('serviceWorker' in navigator) {
// Register the service worker file
navigator.serviceWorker.register('/sw.js')
// Registration succeeded
.then(reg => console.log('Service Worker registered:', reg.scope))
// Registration failed
.catch(err => console.error('Service Worker registration failed:', err));
}
In sw.js, you handle the install and activate events. During installation you usually cache your core assets.
// sw.js
self.addEventListener('install', event => {
console.log('Service Worker installing...');
event.waitUntil(
caches.open('v1').then(cache => cache.addAll([
'/',
'/index.html',
'/styles.css',
'/script.js'
]))
);
});
self.addEventListener('activate', event => {
console.log('Service Worker activated');
});
With the fetch event, the service worker can respond with cached content and fall back to the network when needed.
// Intercept fetch requests
self.addEventListener('fetch', event => {
// Respond with cached resource if available
event.respondWith(
caches.match(event.request)
// If not cached, fall back to the network
.then(response => response || fetch(event.request))
);
});
sw.js.install event fires and the service worker opens cache "v1", adding the listed files to it.activate runs, and the worker becomes active (ready to control pages in its scope).fetch handler checks the cache first:
fetch(event.request) and gets it from the network.localhost during development).v1, v2) and clean up old ones during activate.'serviceWorker' in navigator before registering.index.html, styles.css, and script.js, then register a service worker.sw.js, cache your homepage and CSS file during the install event.v1 to v2) and, in the activate event, delete the old cache.fetch handler that serves a custom offline HTML page when the user is offline.