Reference

Registration & first lifecycle

Compressed sheet for the first service worker path. Normative depth: Archibald lifecycle, MDN register().

Register (page)

if ("serviceWorker" in navigator) {
  window.addEventListener("load", () => {
    navigator.serviceWorker
      .register("/sw.js") // URL relative to origin, not the current page file
      .then((reg) => console.log("registered", reg.scope))
      .catch((err) => console.error("SW register failed", err));
  });
}

Scope

First service worker path

1. register()

Browser downloads, parses, and executes the SW script.

2. install

First event. Precache with event.waitUntil(promise). Fail the promise → SW discarded; never controls clients.

3. activate

Ready for functional events. Cleanup old caches here on updates (later lesson).

4. control

By default the page that first registered is not controlled until a later navigation/refresh. navigator.serviceWorker.controller may be null on first visit.

Inside the worker (minimal)

// sw.js — ServiceWorkerGlobalScope (self)
self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open("static-v1").then((cache) => cache.addAll(["/", "/app.js"]))
  );
});

self.addEventListener("activate", (event) => {
  // first SW: often empty; updates use this for cache cleanup
});

// Optional: take control of already-open pages (timing-sensitive)
// self.addEventListener("activate", (event) => {
//   event.waitUntil(self.clients.claim());
// });

register vs control (steal this)

Concept Means
Registered Browser is managing this script/scope
Installed install succeeded (deps like precache OK)
Activated Can handle functional events when controlling
Controlling this page navigator.serviceWorker.controller !== null — fetches go through SW