What I am trying to achieve:
render page with loader/spinner
if service-worker.js
is registered and active, then check for updates
updatefound
and new version installed, then reload the pageservice-worker.js
updatefound
, meaning new one was installed, remove loaderI am using sw-precache
module for me to generate service-worker.js
and following registration code:
window.addEventListener('load', function() {
// show loader
addLoader();
navigator.serviceWorker.register('service-worker.js')
.then(function(swRegistration) {
// react to changes in `service-worker.js`
swRegistration.onupdatefound = function() {
var installingWorker = swRegistration.installing;
installingWorker.onstatechange = function() {
if(installingWorker.state === 'installed' && navigator.serviceWorker.controller){
// updated content installed
window.location.reload();
} else if (installingWorker.state === 'installed'){
// new sw registered and content cached
removeLoader();
}
};
}
if(swRegistration.active){
// here I know that `service-worker.js` was already installed
// but not sure it there are changes
// If there are no changes it is the last thing I can check
// AFAIK no events are fired afterwards
}
})
.catch(function(e) {
console.error('Error during service worker registration:', e);
});
});
After reading the spec it is clear that there are no handlers for something like updatenotfound
. Looks like serviceWorker.register
checks if service-worker.js
changed internally by running get-newest-worker-algorithm, but I cannot see similar methods exposed via public api.
I think my options are:
onupdatefound
is firedservice-worker.js
code if cache was not updatedAny other suggestions?
Edit:
I've came up with some code which solves this issue by using postMessage()
between SW registration and SW client (as @pate suggested)
Following demo tries to achieve checks through postMessage
between SW client and SW registration, but fails as SW code is already cached DEMO
Edit:
So by now it looks like I cannot implement what I want because:
onupdatefound
, there is nothing else that will notify of changes in SWactivation
of older SW comes before onupdatefound
activation
update()
is immature, keeps changing, Starting with Chrome 46, update() returns a promise that resolves with 'undefined' if the operation completed successfully or there was no update
update() The update() method of the ServiceWorkerRegistration interface attempts to update the service worker. It fetches the worker's script URL, and if the new worker is not byte-by-byte identical to the current worker, it installs the new worker.
You can look at Service Worker Detector, a Chrome extension that detects if a website registers a Service Worker by reading the navigator. serviceWorker. controller property. It might also work in other browsers supporting Web Extensions, but it looks like it is not yet distributed as such.
The other answer, provided by Fabio, doesn't work. The Service Worker script has no access to the DOM. It's not possible to remove anything from the DOM or, for instance, manipulate any data that is handling DOM elements from inside the Service Worker. That script runs separately with no shared state.
What you can do, though, is send messages between the actual page-running JS and the Service Worker. I'm not sure if this is the best possible way to do what the OP is asking but can be used to achieve it.
I have myself kept SW version number in a variable inside the SW. My SW has then posted that version number to the page and the page has stored it into the localStorage of the browser. The next time the page is loaded SW posts it current version number to the page and the onmessage handler compares it to the currently stored version number. If they are not the same, then the SW has been updated to some version number that was included in the mssage. After that I've updated the localStorage copy of the version number and done this and that.
This flow could also be done in the other way around: send a message from the page to the SW and let SW answer something back, then act accordingly.
I hope I was able to explain my thoughts clearly :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With