← Back to Chapters

JavaScript Service Workers

?️ JavaScript Service Workers

⚡ Quick Overview

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.

? Key Concepts

  • Background script: Runs independently of the page and can stay alive even when the page is closed.
  • Registration: You register a service worker from your main JavaScript file using navigator.serviceWorker.register().
  • Scope: The URL path where the service worker controls pages (usually the same folder and below).
  • Lifecycle: Service workers move through install → activate → idle states.
  • Caching: They can cache assets using the Cache API to enable offline-first experiences.
  • HTTPS only: Service workers require a secure context (HTTPS or localhost for development).

? Syntax and Lifecycle Theory

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.

? Code Examples

? Registering a Service Worker

Registration is done from your main JavaScript file (for example, app.js or inside a script tag in your HTML).

? View Code Example
// 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));
}

⚙️ Installing and Activating the Service Worker

In sw.js, you handle the install and activate events. During installation you usually cache your core assets.

? View Code Example
// 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');
});

? Intercepting Fetch Requests and Serving Cache

With the fetch event, the service worker can respond with cached content and fall back to the network when needed.

? View Code Example
// 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))
);
});

? What This Service Worker Does

  • First visit: When the user visits your site, the browser runs the registration code and downloads sw.js.
  • Install phase: The install event fires and the service worker opens cache "v1", adding the listed files to it.
  • Activate phase: After installation, activate runs, and the worker becomes active (ready to control pages in its scope).
  • Fetch handling: For every network request, the fetch handler checks the cache first:
    • If the resource is cached, it returns the cached version (fast and works offline).
    • If not, it falls back to fetch(event.request) and gets it from the network.
  • Offline behavior: When the user is offline, any cached file is still served, providing an offline-friendly experience.

? Use Cases and When to Use

  • Building Progressive Web Apps (PWAs) with offline support.
  • Caching static assets (HTML, CSS, JS, images) for faster load times.
  • Providing a custom offline page when the user has no network.
  • Implementing background sync to send data when the connection is restored.
  • Handling push notifications for web-based messaging or updates.

? Tips and Best Practices

  • Always serve service workers over HTTPS (or localhost during development).
  • Version your caches (e.g., v1, v2) and clean up old ones during activate.
  • Cache only what you really need to keep the size manageable.
  • Use the browser DevTools (Application tab) to inspect service workers and caches.
  • Always check for browser support with 'serviceWorker' in navigator before registering.

? Try It Yourself

  • Create a simple website with an index.html, styles.css, and script.js, then register a service worker.
  • In sw.js, cache your homepage and CSS file during the install event.
  • Update the cache name (for example, from v1 to v2) and, in the activate event, delete the old cache.
  • Add a fetch handler that serves a custom offline HTML page when the user is offline.
  • Open DevTools, go to the Application tab, and experiment with the "Offline" checkbox to test your service worker.