vite-pwa / vite-plugin-pwa

Zero-config PWA for Vite

Home Page:https://vite-pwa-org.netlify.app/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

docs: relationship between "registerType", "onNeedRefresh" and "onRegistered".

danielyogel opened this issue · comments

From reading the guides I personally don't understand the relationship between "registerType", "onNeedRefresh" and "onRegistered".
For example, if I set registerType: 'autoUpdate':

  1. Do I still need to configure "onNeedRefresh" with a call to "updateSW"? or is that redundant?
  2. Do I still need to follow the "Periodic Service Worker Update" guide and set an interval inside "onRegistered"?

If I guess correctly, the "auto-update.html" and "prompt-for-update.html" guide are mutually exclusive, while the "periodic-sw-updates.html" is relevant for both of them.
Am I right?
Thanks for this great plugin.

@danielyogel I use strategy for both strategies and registerType options: former for build time and latter for client behavior/strategy

  1. onNeedRefresh will never be called since you're using auto update client strategy (registerType): it will be called only when using prompt client strategy and a new sw detected. onOfflineReady will be called once the sw is registered first time: the callback will be called in both client strategies.
  2. onRegistered will be always called if provided from sw registration callback, just check https://github.com/antfu/vite-plugin-pwa/blob/main/src/client/build/register.ts#L83

Yes, autoUpdate and prompt client strategies (registerType) are mutually exclusive, you can only configure one client strategy on plugin options.

About the periodic sw updates:

While your users are using the app, there is no way to hint the browser there is a new app version (you can deploy it at any time). Periodic sw updates will just ping the server to check if the sw has changed: once sw change the browser will try to install it: if using autoUpdate client strategy then the sw will be activated and all clients (page/tabs/another browser instances) using it will be reloaded, while using prompt client strategy the sw will keep in skip waiting state awaiting user confirmation, once the client/user confirms its installation the browser will proceed with its activation (the same process previously described for autoUpdate client strategy.

I don't use periodic sw updates: you can use server push notifications instead but not all browser support it. periodic sw updates is the simplest strategy to keep the app updated.

Depending on the type of application it may be necessary that you have to use it:

  • For example, if the application is something critical, you can use web sockets and register all clients to be notified (it would be similar to server push notifications), so once a new version of the application is deployed, you send a notification to all clients and it would only be necessary to add the logic to update the app (for example, saving the reference to the sw via onRegistered and calling it when the notification is received from the web socket).
  • On the other hand, if it is not something critical, users usually turn off the computer or close the browser or if it is on the mobile, put the browser in the background, once the application is navigated, it is usually reloaded and if there is a new version the browser will take care of activating the update process

you can take a look at this issue (take your time, it is huge): #33

check #33 (comment) and a few comments I made in response

@userquin Many thanks for the detailed answer!

I use strategy for both strategies and registerType options

I don't really understand this sentence... :\ I've defined only "registerType", anyway.

I don't use periodic sw updates:

I understand I may just leave it off, and the app eventually will update when navigated, but what about "installed" (added to home screen) apps?

you can use server push notifications instead

If I do decide to use periodic updated, using push and web sockets - how do I know that an asset was changed in the backend, do I do it manually by inspecting the files?

const updateSW = registerSW({
  onRegistered(r) {
    r && setInterval(() => {
      r.update()
    }, intervalMS)
  }
})

What exactly r.update() does? is this call just refreshes current browser? is it triggering some request to the server to check for new assets?

Thanks again!

@danielyogel

There are 2 plugin options: strategies (default is generateSW) and registerType (default is prompt), I use strategy to refer both, former for build time and latter for client behavior.

r.update() will ping the sw url to the server (via GET or HEAD), if changed then will proceed to install it in the background without refreshing the page: browser will start download new app version (all assets listed on the sw precache manifest), once pre cache manifest dowenloaded, it will emit new sw available event and depending the registerType will proceed as explained on previous entry.

vite will emit your assets using some hash algorithm (sha256) and so all stuff unchanged will be generated with the same hash. Just check the sw.js on your app on source dev tools, see precacheAndRoute() method (seescreenshot below). Check also this article https://css-tricks.com/vitepwa-plugin-offline-service-worker/, you will find some reference how the pwa works (the cache and versioning). You can try to build your app twice, the content will be the same (if nothing changed).

If you will use web socket, you'll need to add some functionality on your app to allow send you the web socket event as administrator, and then send the event once the new app is deployed and available. If you send that web socket event and the r.update() result is that the sw is not changed, then there will not be app update (just like if you refresh the page and no new app deployed/changed).

imagen

Thanks for the detailed response!

A few more questions, if that's fine:

  1. If I use registerType: 'autoUpdate', and never configure onRegistered at all - will the app still update when reloaded - or I have to call onRegistered(r) {r.update()} at least once? (I'm not interested in periodic update).
  2. When I use registerType: 'autoUpdate' - does that can cause a flickering when loading the app, everytime? I see some flickering when loading my webapps which are configured this way.
  3. Does registerType: 'autoUpdate' updates the webapp immediately when loading it? or does it takes some time?

@danielyogel

  1. onRegistered is optional so you don't need to worry about it, the app will be auto updated with a page reload: the check for new sw will only occur when entering the page or a page refresh (this is why we include the periodic check for updates)
  2. should be only a flickering only when received an updated and reloading the page
  3. no, the time will depend on the app size: when the sw detects a new version, it will try to install all new resources (downloading all resources), then, the current sw will fire a page reload forcing the new sw version to take the control of all opened client/tabs where the app is running