jsnotes

Topic 006: Service workers in JS

Topic 006: Service workers in JS

A Service Worker is a script that runs in the background of the browser, separate from the web page, enabling features that don’t need a web page or user interaction. These features include handling network requests, caching assets, and enabling push notifications. Service Workers are a key component of Progressive Web Apps (PWAs).

Key Features of Service Workers:

  1. Background Sync: They allow you to defer actions until the user has stable connectivity.
  2. Push Notifications: They enable push notifications from the server.
  3. Caching: They help to cache assets and resources to enable offline access.

Registering a Service Worker

To use a Service Worker, you must register it in your web page’s JavaScript code. The registration process tells the browser where your Service Worker script is located.

Example

if ("serviceWorker" in navigator) {
  window.addEventListener("load", () => {
    navigator.serviceWorker
      .register("/service-worker.js")
      .then((registration) => {
        console.log("ServiceWorker registration successful with scope: ", registration.scope);
      })
      .catch((error) => {
        console.log("ServiceWorker registration failed: ", error);
      });
  });
}

Writing a Service Worker Script

The Service Worker script handles various events like install, activate, and fetch.

Example: service-worker.js

const CACHE_NAME = "my-cache-v1";
const urlsToCache = ["/", "/styles/main.css", "/script/main.js"];

// Install event
self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => {
      console.log("Opened cache");
      return cache.addAll(urlsToCache);
    })
  );
});

// Activate event
self.addEventListener("activate", (event) => {
  const cacheWhitelist = [CACHE_NAME];
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames.map((cacheName) => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

// Fetch event
self.addEventListener("fetch", (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      // Cache hit - return the cached response
      if (response) {
        return response;
      }
      return fetch(event.request).then((response) => {
        // Check if we received a valid response
        if (!response || response.status !== 200 || response.type !== "basic") {
          return response;
        }

        // Clone the response
        const responseToCache = response.clone();

        caches.open(CACHE_NAME).then((cache) => {
          cache.put(event.request, responseToCache);
        });

        return response;
      });
    })
  );
});

Detailed Explanation:

  1. Install Event:

    • This event is triggered when the Service Worker is installed.
    • In this event, we open a cache and add the specified resources (urlsToCache) to it.
  2. Activate Event:

    • This event is triggered after the Service Worker is installed.
    • It is used to clean up old caches that are no longer needed.
  3. Fetch Event:

    • This event is triggered for every network request.
    • It intercepts the requests and responds with cached resources if available. If not, it fetches the resource from the network, caches it, and then returns it to the user.

Benefits:

By leveraging Service Workers, you can create more resilient, faster, and offline-capable web applications.