Removing a Service Worker
Posted
Background
I used to use a Service Worker on this blog to provide some minor features. This worker did a grand total of two things:
- It allowed using a stale page while checking the network for an updated version, or on a network error.
- It preloaded the homepage (but no related assets).
The first is fairly useful, it provided a snappier experience for anyone revising a page, and the second I guess was a slight experience upgrade.
However times have moved on and the first feature can be provided by stale-while-revalidate and stale-if-error. The former of which is now supported by browsers. Since stale-if-error
isn’t supported I am losing a minor feature but as a static site my website isn’t down very often (🤞).
The second feature can probably be supported via a prefetch link but I’m not even sure I want to do that at this point.
I have seen a lot of solutions online, however none were clear and all had problems.
Goals
- Remove the service worker at some point in the future. Since my service worker was working (mostly) correctly there was no urgent need to remove it. However I would like it to eventually go away.
- Avoid leaving code on the live pages. I would like to have an optimized experience for future views.
- Ideally clean up the caches. I only had one cache, and the documents in it were tiny but it would be nice to clean up after ourselves.
Solution
- Delete the code that registers the service worker.
- Replace the service worker script with the following file. The new code must be available from the same URL the previous service worker was at. If you had multiple service worker URLs in the past you should duplicate the code at all of them.
console.log("Cleanup Service Worker Starting");
caches.keys()
.then(keys =>
Promise.all(
keys.map(async key => console.log("caches.delete", key, await caches.delete(key)))))
.then(async () => {
console.log("registration.unregister", await registration.unregister());
})
.then(() => console.log("DONE"))
.catch(console.error);
This code is fairly straight forward. First it deletes all the caches, then it unregisters itself.
Users’ browsers will automatically check for an updated service worker the next time they load your website, or the next event 24h after the last service worker check. This means that existing users will run this cleanup on their next visit.
Avoided Issues
Live Code
All the other solutions I saw online replaced the registration code with code that listed all of the registrations and removed them. The major issue with this is that it means that this unregister code will run on every future page load of your site.
Another issue is that in theory you can also never remove this code, as someone who hasn’t visited your site in the meantime will still have their service worker active. So while running that code on every page load is a trivial amount of resources I would prefer to avoid it if possible.
Deleting the Service Worker
Simply deleting the worker file will not remove the worker. I couldn’t find the revelant section of the sepcification however Google’s Web Fundamentals page clearly states that a 404 will leave the current service worker active. I suspect that it won’t survive forever, as that seems like a poor behaviour, but it doesn’t seem that there is consensus that it will be removed at some point.
So I plan to keep my /service-worker.js file around forever …or at least until I decide that I want a service worker again 😆