I want to be able to fully control my Service Worker verions,
I created signals and functions that allow me to update or skipWaiting an exsting Service Worker which works prefect!
self.addEventListener('install',event=>
event.waitUntil(caches.open(version).then(cache=>
cache.addAll([
...
]).then(_=>
condition?
self.skipWaiting():
false
)
))
)
self.addEventListener('activate',event=>
event.waitUntil(clients.claim())
)
When I call skipWaiting, the client page is claimed by the new Service Worker as it supposed to,
But I can't make it immediately reload from the new cache of the newly installed Service Worker.
How can I skipWaiting and force all clients pages to reload themself from the cache of the newly installed Service Worker?
Try this code snippet:
// If service workers are supported...
if ('serviceWorker' in navigator) {
// Check to see if the page is currently controlled.
let isControlled = Boolean(navigator.serviceWorker.controller);
// Listen for a change to the current controller...
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (isControlled) {
// ...and if the page was previosly controlled, reload the page.
window.location.reload();
} else {
// ...otherwise, set the flag for future updates, but don't reload.
isControlled = true;
}
});
}
I'd recommend basing this logic on the controllerchange event rather than some other approaches, like listening to the statechange of an installing/waiting service worker, since there's a small gap in time between when a service worker activates and when it takes control of existing clients. Waiting on each page for the controller to change will guarantee that the reload takes place under control of the updated service worker.
Using this code in conjunction with a service worker that calls skipWaiting() should give you the behavior you're looking for.