Angular documentation provides following example to activate an SW update:
constructor(updates: SwUpdate) {
updates.available.subscribe(event => {
if (promptUser(event)) {
updates.activateUpdate().then(() => document.location.reload());
}
});
}
From what I observe, the call itself is not sufficient to activate new version, reload is necessary. However document.location.reload()
is sufficient even without activateUpdate()
call.
What is the purpose of activateUpdate()
call? Why call it at all when reload suffice?
The SwUpdate service gives you access to events that indicate when the service worker has discovered an available update for your application or when it has activated such an update—meaning it is now serving content from that update to your application. The SwUpdate service supports four separate operations:
This basically depends on how browsers assign Client. id on reloads. If the browser assigns a new ID to the tab on reload, then the SW will serve the latest version anyway, so swUpdate. activeUpdate () is not necessary. If, on the other hand, the browser keeps the same client ID, then the SW would serve the old version without swUpdate.
From the github code, what I understand is, an activateUpdate () will do a postMessage () to the service worker thread to let it know about the new data and status and once the promise has been resolved (service worker thread knows about it), then reload the page.
Some background on what the Angular ServiceWorker does under the hood: There is always one version of the SW, but it can have multiple versions of the app. It keeps a mapping of client IDs to app versions, so it knows which version to serve to each client. When a new version is found, it downloads it and marks it as the latest version.
Some background on what the Angular ServiceWorker does under the hood:
This behavior is a little different than how ServiceWorkers usually work. It is designed to allow serving the latest version to new clients, but not break existing ones (by serving them new content that is not designed to work with the older HTML/CSS/JS code they are using already).
Now, back to activeUpdate()
:
This basically tells the SW to assign the latest version to the client. Once the operation completes, new requests from the client will be served with the latest app version. This is not safe, therefore it is recommended to reload the page to ensure that all code comes from the new version.
Does simply reloading suffice?
This basically depends on how browsers assign Client.id
on reloads. If the browser assigns a new ID to the tab on reload, then the SW will serve the latest version anyway, so swUpdate.activeUpdate()
is not necessary. If, on the other hand, the browser keeps the same client ID, then the SW would serve the old version without swUpdate.activeUpdate()
.
Currently, Chrome seems to assign a new ID (and therefore activeUpdate()
is unnecessary before reload). I couldn't find something conclusive in the SW spec, so I am not sure whether this is per the spec and whether all browsers do the same.
(It is also possible that browsers used to behave differently in the past, making activeUpdate()
necessary, but the spec/browsers have been updated since, making it redundant if you plan to reload.)
So, if you verify that your supported browsers behave as expected in that regard, then you don't need to call activeUpdate()
before reloading.
Note that the documentation example is just a simplified illustration of the APIs that are available. In a real app, there are several ways to handle the update (depending on the app's requirements).
For example, you could:
Again, not all strategies are suitable for all types of apps, so choose the one that works best for you.
EDIT:
BTW, if you have suggestions on how the documentation could be improved, please open an issue (or better yet submit a pull request)!
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