56376

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

<h3>Question</h3>

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?


<h3>Answer1:</h3>

Some background on what the Angular ServiceWorker does under the hood:

<ul><li>There is always one version of the SW, but it can have multiple versions of the app.</li> <li>It keeps a mapping of [client IDs] to app versions, so it knows which version to serve to each client.</li> <li>When a new version is found, it downloads it and marks it as the latest version.</li> <li>From that point onwards, new clients (e.g. new tabs) will be served that latest version, but existing clients (tabs) will still get the previous version.</li> </ul>

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

<hr />

Now, back to activeUpdate():

This basically tells the SW to set the client to the latest version. Once the operation completes, new requests from client will be served 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.

<hr />

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

<hr />

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:

<ol><li>Activate the update immediatelly (if you are certain that your app can handle that) and not reload.</li> <li>Show a notification that an update is available and let the user click to reload (And thus update).</li> <li>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.)</li> </ol>

<sub>Again, not all strategies are suitable for all types of apps, so choose the one that works best for you.</sub>

<hr />

<em>EDIT:</em>
<em>BTW, if you have suggestions on how the documentation could be improved, please open an issue (or better yet submit a pull request)!</em>


<h3>Answer2:</h3>

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.

https://github.com/angular/angular/blob/7.2.11/packages/service-worker/src/update.ts#L57-L64

activateUpdate(): Promise<void> { if (!this.sw.isEnabled) { return Promise.reject(new Error(ERR_SW_NOT_SUPPORTED)); } const statusNonce = this.sw.generateNonce(); return this.sw.postMessageWithStatus('ACTIVATE_UPDATE', {statusNonce}, statusNonce); }

https://github.com/angular/angular/blob/master/packages/service-worker/src/low_level.ts#LC105

postMessageWithStatus(type: string, payload: Object, nonce: number): Promise<void> { const waitForStatus = this.waitForStatus(nonce); const postMessage = this.postMessage(type, payload); return Promise.all([waitForStatus, postMessage]).then(() => undefined); }

来源:https://stackoverflow.com/questions/55494181/what-is-the-purpose-of-swupdate-activateupdate-in-angular

Recommend

  • 安装vnc客户端、、安装vnc的客户端
  • How to bind View Date to model milliseconds with Angularjs
  • Ms-Access: Concatenation, Create Alias, Use Alias
  • How can a function find a parent element of the anchor which originally called the function?
  • Is it possible to serialize string to json with single slashes?
  • TeamCity: Scripting elements jsp:declaration, jsp:expression, jsp:scriptlet are disallowed here
  • React Linting: Unclosed Regular Expression
  • How to detect user changing sheet?
  • Rezize HTML Canvas size after transformed operation
  • Why context.Wait in StartAsync didn't stop the dialog
  • Firebase reverse dns lookup ENOTFOUND error node.js dns
  • Stop the background service after particular time in android
  • PushPlugin not found, or is not a CDVPlugin
  • How to set title name of the pdf. While viewing the Document(New Tab)
  • password_hash() not working [closed]
  • Static analysis of header inclusion in C++
  • Authorization Policies/Gates for Laravel 5.3 web app consuming own API w/ Passport
  • How to gracefully stop python unittest?
  • View.layout() works until next UI update
  • NHibernate add unmapped column in interceptor
  • How to assert page/tab/window title in Behat + Mink
  • device tree overlay phandle
  • Facebook like button redirect? [closed]
  • Dynamic reference casting depending on actual object type
  • Xmlserializer to C# object, store original XML element
  • yii rewrite url with many sub categories
  • MayAVI install on Python 3.6 [duplicate]
  • Keep rows with certain values always at the bottom while sorting in jquery tablesorter plugin
  • Run a form (insert/update/delete) from within a div using jquery
  • python selenium scraping tbody
  • Visual Studio 2017 Professional- Unable to find package at source
  • How to redirect into different page by user type in php and mysql
  • How to resolve this in PHPUnit where it is asking me to set KERNEL_DIR in my phpunit.xml?
  • How do I use libcurl to printf a remote FTP directory listing?
  • How to create subsets of a single set of elements with XSLT?
  • JQuery: Infinite input select
  • Android: Unable to detect vertical plane
  • Debug `Unexpected end of JSON input Error` on content script
  • Apple Mach-O Linker error (“duplicate symbol”)
  • Angular FormGroup won't update it's value immediately after patchValue or setValue