Service Workers: An Introduction
notes date: 2017-11-09
source date: 2017-10-04
Service Workers: An Introduction https://developers.google.com/web/fundamentals/primers/service-workers/
What is a service worker
- a script your browser runs in the background without ajax requests, e.g.
- push notifications
- background sync
- [future] periodic sync
- [future] geofencing
- intercept and handle network requests (incl. managing a cache of responses), e.g. to support offline experience
- designed as a replacement of AppCache API
- about it
- it’s a programmable network proxy; it can’t access the DOM directly, but it can respond to messages sent via postMessage
- terminated when not in use, and restarted on-demand, so handlers should handle state explicitly (via IndexedDB API)
- uses Promises
The service worker life cycle
- your page’s JS registers the service worker
- this initiates an installation
- typically involves downloading and caching of some static assets
- if installation succeeds, activation begins
- this is the spot you probably want to manage old cached versions of the static assets that control the service worker’s behavior
- after activation, the SW controls all pages that fall under its scope.
- SW can be in one of three states:
- idle
- terminated to save memory
- handling fetch and message events that occur when a network request or message is initiated from your page
- this initiates an installation
Prerequisites
Browser support
You need HTTPS
- SW can be used to hijack connections, fabricate responses, or filter responses.
- In order to safeguard against this, you can only register SWs on pages served over HTTPS
Register a service worker
- navigator.serviceWorker.register(LocationOfServiceWorkerFile)
- if LocationOfServiceWorkerFile is /foo.js, then the scope of foo.js is the entire origin; if it is /bar/foo.js, then its scope is fetch events to /bar to the origin.
Install a service worker
- in the service worker script, we define an ‘install’ callback
- typically, it opens a cache, caches our files, and confirms whether all cache attempts succeeded, and we want installation to fail if any of the files failed to install
Cache and return requests
- on page loads subsequent to the one that installs a SW, the SW begins to intercept fetch events.
- Hooking into this you can cache results as-is, or even incrementally add to/replace results already cached.
Update a service worker
- Steps to update a SW
- update your service worker’s javascript file
- if the file is at all different from the client’s cached copy, it considers it new
- your new SW will be started and an install event will fire
- the old SW is still controlling currently-open pages, so the new SW will enter a waiting state
- when the currently open pages are closed, the old SW will be killed and the new SW will take control
- once the new SW takes control, its ‘activate’ event will be fired
- Good practices
- often old SW and new SW will require differently formatted data in cache; it’s best to flush the cache not on install but on activate, so that updating the SW doesn’t flush on new version’s activate (while old version is still running), but when new version begins to take control
Rough edges and gotchas
If installation fails, we’re not so good at telling you about it
The defaults of fetch()
No credentials by default
fetch() sends credentials opt-in (rather than opt-out) – unlike XHR, more like other CORS requests