Learnitweb

What is a Service Worker?

1. Introduction

A Service Worker is a powerful feature in modern web development that enables your web applications to run in the background—even when the browser is closed—and to provide rich offline experiences, background syncing, and push notifications.

It is an essential building block of Progressive Web Apps (PWAs).

2. What is a Service Worker?

A Service Worker is a JavaScript file that:

  • Runs independently of your main web page (browser thread)
  • Acts like a proxy server between your web application, the browser, and the network
  • Allows you to intercept and handle network requests
  • Can cache responses, enabling offline access to parts (or all) of your app
  • Supports background tasks like push notifications and syncing data in the background

3. Key Characteristics of a Service Worker

  1. Runs in the Background
    • A service worker is not tied to any specific web page.
    • It runs in a separate context, meaning even if your app is closed, it can still handle events like push notifications.
  2. Event-Driven
    • Service workers don’t run all the time. They wake up to respond to events like:
      • install – when the service worker is being installed
      • activate – when it becomes active
      • fetch – when the page makes a network request
      • push – when a push notification arrives
      • sync – when background sync happens
  3. Intercepts Network Requests
    • Service workers can listen to all outgoing requests made by your app and decide:
      • Whether to serve cached content
      • Whether to fetch from the internet
      • Whether to show a fallback message/page
  4. Secure Context Only
    • Service workers only work on HTTPS (or on localhost during development) because they can intercept network traffic and must not be vulnerable to attacks.
  5. Asynchronous and Promise-Based
    • All service worker APIs use Promises, which helps in managing asynchronous operations like caching, responding to fetch events, etc.

4. Why is it Useful?

Use CaseBenefit
Offline SupportEnables web apps to work even without internet by serving cached files.
Faster Load TimesCached assets load instantly, making apps feel snappy and responsive.
Push NotificationsKeeps users engaged with real-time updates even when the app is closed.
Background SyncSyncs data when the network becomes available, useful for forms or messages.
Control Over RequestsDecide how requests are handled—cache-first, network-first, stale-while-revalidate, etc.

5. How Does a Service Worker Work? (Step-by-Step)

5.1 Registration

The service worker is registered from your web page using:

navigator.serviceWorker.register('/sw.js');

This tells the browser to install and manage the /sw.js file as a service worker.

5.2 Installation

The install event is triggered once, the first time the service worker is registered. You usually cache static assets here using the Cache API.

5.3 Activation

After the service worker is installed, the activate event is fired. This is where you clean up old caches or update assets if needed.

5.4 Fetching

When the user opens your site again, the service worker intercepts all network requests. It can decide to serve them from cache or fetch them from the internet.

5.5 Lifecycle Management

Service workers are automatically terminated when not in use and restarted when needed. This means they don’t consume memory when idle.

6. Minimum Requirements to Use a Service Worker

  • Must be served over HTTPS
  • Must be registered from the root or a subfolder
  • Only modern browsers support it (but support is widespread)

7. Example Capabilities Beyond Caching

FeatureDescription
Push NotificationsReceive and display messages from the server even when the app is closed
Background SyncWait until the device is online, then send queued data (e.g., form submissions)
Periodic Background SyncSchedule regular sync events
Navigation PreloadSpeed up page loads by allowing parallel loading and SW boot

8. Example of Service Worker

8.1 Project Structure

/my-pwa
│
├── index.html
├── sw.js
└── manifest.json   ← optional for now

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Simple PWA</title>
</head>
<body>
    <h1>Hello, this is a basic PWA</h1>
    <p>If you're offline, this page can still load.</p>

    <script>
        // Register the service worker
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('sw.js')
                .then(reg => console.log('Service Worker registered:', reg.scope))
                .catch(err => console.error('Service Worker registration failed:', err));
        }
    </script>
</body>
</html>

sw.js (Service Worker)

// Service worker install event
self.addEventListener('install', function(event) {
    console.log('[ServiceWorker] Install');
    event.waitUntil(
        caches.open('my-cache-v1').then(function(cache) {
            return cache.addAll([
                './index.html'
            ]);
        })
    );
});

// Service worker fetch event
self.addEventListener('fetch', function(event) {
    event.respondWith(
        caches.match(event.request).then(function(response) {
            // Return the cached response if available, otherwise fetch from network
            return response || fetch(event.request);
        })
    );
});

Now run the application locally.

8.2 How to Test Offline Support

  • Open your app in Chrome.
  • Open DevTools → Application tab → Service Workers → Check “Offline”.
  • Reload the page — it will load from the cache!

9. Understanding Code

9.1 Install Event

self.addEventListener('install', function(event) {

This tells the service worker what to do when it’s first installed in the browser.

    event.waitUntil(
        caches.open('my-cache-v1').then(function(cache) {
            return cache.addAll([
                './index.html'
            ]);
        })
    );
  • event.waitUntil(...) ensures the service worker doesn’t finish installing until the code inside completes.
  • caches.open('my-cache-v1') opens a named cache storage.
  • cache.addAll([...]) adds the index.html file to the cache so it can be served later (even offline).

9.2 Fetch Event

self.addEventListener('fetch', function(event) {

This listens for any network request made by your web page (e.g., when loading HTML, CSS, images, etc.).

    event.respondWith(
        caches.match(event.request).then(function(response) {
  • event.respondWith(...) tells the browser to respond to the request with a custom response (our own logic).
  • caches.match(event.request) checks if the requested file is already in the cache.
            return response || fetch(event.request);
  • If the file is in the cache (response exists), return it.
  • Otherwise, fetch it from the network.