Service Workers

Introduction

Service Workers is one of the superpowers PWAs have. A Service Worker is a JavaScript file that runs in the background in a separate thread and can, for instance, intercept network requests and handles push messages.

Ever heard of a Man-in-the-middle attack or Monster-in-the-middle attack? An attacker will intercept all communication between two parties through for instance unencrypted website communication or an unprotected (public) WiFi access point.

You can think of Service Workers being a benign Man-in-the-middle. I like to call it Marvel-in-the-middle. 😉

Key features

The key features of marvellous Service Workers:

  • as said: they run in a separate thread on the background; so it isn't blocking
  • because of that: they aren't tied to a particular page but are scoped to your website
  • and also because of that: they aren't able to modify a page; they have no access to the DOM
  • are HTTPS only; for a good reason. With great power comes great responsibility! (will work on localhost)
  • are fully asynchronous (no callbacks, but promises (or async/await)!)
  • are event-driven; pick and choose events you want to hook into
  • keep running; even after you closed the tab your website is running in; on mobile even when the browser is closed

Service Worker Lifecycle

TODO: Create a new diagram of it

Service Worker Lifecycle

  • a user navigates to a URL
  • Registration process starts
  • the browser downloads the Service Worker
  • Service Worker is parsed
  • Service Worker is executed
  • After executing, the Install event is activated
  • If successful, the Service Worker is ready to handle events

The first time you load a web page without an active Service Worker, it will not handle any requests coming or going. It needs to be installed and activated first. The Service Worker will do it's marvels when you refresh or navigate to another page.

The browser will always run the registration process when you refresh the page or visit another one. Only if your Service Worker file (sw.js) has changed, it will install it.

Place your Service Worker file (sw.js) in the root of your website.

Events

Register

Add the registration of your Service Worker in a JavaScript file (e.g. app.js) that is used on every page.

// app.js

// check if Server Workers are supported
if ("serviceWorker" in navigator) {
  // register your Service Worker
  navigator.serviceWorker
    .register("/sw.js")
    .then(() => {
      // callback when succeeded
      console.log("Service Worker registered!");
    })
    .catch(err => {
      console.log(err);
    });
}

Install

// sw.js

self.addEventListener("install", event => {
  console.log("[Service Worker] Installing Service Worker ...", event);
});

Activate

// sw.js

self.addEventListener("activate", event => {
  console.log("[Service Worker] Activating Service Worker ...", event);
  // ensure that the Service Worker is actived correctly (fail-safe)
  return self.clients.claim();
});

A Service Worker will not be activated as long as the website is still open. This is because it might still be communicating with the old Service Worker and a new Service Woker might break this.

You can close and open the website or use the Chrome Developer Console tools to activate the new Service Worker.

TODO: How to handle that for users.