Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of SwUpdate.activateUpdate() in Angular?

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?

like image 266
Vilmantas Baranauskas Avatar asked Apr 03 '19 11:04

Vilmantas Baranauskas


People also ask

What does the SWUpdate service do?

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:

Does SWUpdate need to be active on reload?

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.

How does the activateupdate () function work?

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.

How does the angular serviceworker know which version of the app?

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.


1 Answers

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.
  • From that point onwards, new clients (e.g. new tabs) will be served that latest version, but existing clients (tabs) will still get their previously assigned version.

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:

  1. Activate the update immediatelly (if you are certain that your app can handle that) and not reload.
  2. Show a notification that an update is available and let the user click to reload (and thus update).
  3. Let the app know that an update is available and have it automatically reload on the next in-app navigation. (This is what we do in https://angular.io/ btw.)

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)!

like image 126
gkalpak Avatar answered Oct 29 '22 06:10

gkalpak