The service workers act as background proxies. When a network request is made through our website, they first go through the service worker that is in use. Thanks to this and other APIs such as caching, we can intercept a network request and immediately return a cached version, obtaining availability against network failures (offline mode), as well as speed by not having to carry the request to the server.
The problem with this strategy known as offline-first is that the saved version is always displayed even if it is not the most current. This problem can be solved in many ways, for example:
Display the saved version and perform in the background a new network request to cache it. After this the user is informed that there is new data to refresh the page and see the new version.
Using cache invalidation techniques to remove the saved version of pages that are out of date.
By creating a new cache on each deployment. This is known as versioning:
cache-v2, etc. Each new deployment invalidates and removes the old caches.
These solutions add a lot of complexity, especially if they are done from scratch without using a library like Workbox.
For these reasons I have changed the strategy of this blog from offline-first to network-first with offline mode. It’s not perfect but it’s a fairly simple way to offer offline mode to already visited pages, while avoiding dealing with pages that become obsolete.
Here’s a curiosity that I admit took me a while to figure out. Can you tell why this doesn’t work?
event.respondWith() do not accept a function as an argument, but a promise. So that you have to call the asynchronous function (for example, via an IIFE) so that it returns a promise and is passed as an argument.
sw.js file starts with the install event. This is executed when the service worker is first installed in the user’s browser.
Then we activate the service worker:
And finally the
fetch event is in charge of intercepting the network requests and managing the entire strategy. Let’s see step by step through the comments.
If you want to access the version of the service worker without comments so you can copy and paste, remember that you have it in /sw.js.