Service workers

Service workers are scripts which browsers can run independently from a web page.

Service workers can intercept network requests, like a proxy. This is commonly used to {implement a custom cache}.

Service workers can’t access the DOM. Instead, they communicate with associated web pages via {postMessage}.

Service workers are started {on-demand} and terminated {when idle}. Their in-memory state is {not persisted}.

Q. What web technology enables background sync?
A. Service workers

Q. What web technology enables push notifications?
A. Service workers

Installing a service worker

Service workers are installed through {a registration API called by Javascript running on a web page}.

During installation, service workers begin in the {installing} state, then transition to {activated} (or {error}) after {all the associated resources are fetched}. Before reaching that state, the service worker may transition to {waiting} until {no pre-existing service worker is controlling an open page}.

Once activated, a service worker {performs one-time startup computation}, then transitions to {idle}. From that state, it’ll handle {fetch or message events} until it eventually terminates.

To cache files during a service worker’s install step, use its global scope’s {caches} property, which represents a {CacheStorage} object. You must first {open a particular cache}, then you can {add specific URLs}. These are asynchronous operations, so you must {use the waitUntil method on the installation event to delay activation}.

While a service worker’s waiting on a promise passed to waitUntil, it will {buffer} inbound events.

Q. What’s the initial-registration gotcha for service workers’ control of web pages?
A. They won’t control the web page which registered them until it’s refreshed, unless that client is specifically claimed.

Updating a service worker

A service worker is updated when {a user visits a web page} and {the registered service worker script doesn’t match the existing one}. You can trigger an update check manually by calling {update()} on {the registration object in the host web page}.

If a service worker needs to significantly change the cached resources on update, it should {wait until it’s been activated} rather than {modifying the cache in the install state} so that {a still-running old service worker doesn’t suddenly become unable to service files from the cache}.

Normally, an updated service worker stays in the waiting state while an old one is still running, but you can supplant it immediately by {calling skipWaiting()} while {in the install phase}.

In the context of {the host web page}, an {updatefound} event is fired on {the registration object} when a service worker updates.

Using a service worker as a network proxy

A service worker’s scope is determined by {the URL prefix of its URL}. It will only control clients which {fall within its scope}. For example, a service worker registered at {/foo/bar.js} would only control clients under {/foo}.

To capture network requests, your service worker should {handle the fetch event}.

When caching the response to a request in a service worker, you should make sure to {store a cloned copy of the response}, since {it’s a stream and the browser will also need to consume it}.


References

Service Workers: an Introduction  |  Web Fundamentals

Last updated 2023-07-13.