'App updates are available' in PWA apps (and service workers) #313
KaiVandivier
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
NB: this UX may change in the near future, but I’ll still add this post in case it’s helpful after that change
Starting recently, you may have seen the prompt in the Dashboards App that says something along the lines of ‘App updates are available’ and an invitation to reload, and since service workers aren't very intuitive, here's a bit of explanation about what's going on in case you’re curious to know or need to know the details of how it works! This description applies to any PWA-enabled apps, but the Dashboards App is the first of these.
In short:
Because of the way we use a service worker script to make the app offline-capable, new updates to the app that have been deployed on the server get downloaded in the background while the ‘old’ app loads, and the updates won’t be visible right away. The updates will be ‘waiting’ until all instances of the app are closed (this is when the prompt is shown) and then activate the next time the app is opened, or until a signal can be sent to ‘skip waiting’ and reload to see the new changes right away (which it what happens when you confirm the prompt).
More technical details of what’s happening:
When you visit
play.dhis2.org/dev/dhis-web-dashboard
, the request forindex.html
and all the scripts, stylesheets, and other bundled assets go through the service worker that’s installed in your browser for that page. (It also checks for a new service worker; more on that below.) The service worker doesn’t request any of the assets over the internet; it downloaded all of those when it installed. (Side note: our service workers only do that in production.)Because it serves app files cache-first without checking the server, if you change the app and deploy it without making and installing a new service worker, that first service worker will still intercept the requests for
index.html
and scripts and return the cached app instead of the new app that’s deployed on the server. This is why sometimes we’ve run into apps ondebug.dhis2.org/dev
orplay.dhis2.org/dev
that mysteriously show an old version of the app, even though the deployed version is new.Now about updating the service worker: when you visit a page, for example
/dev/dhis-web-dashboards/
, the browser loads the app via the service worker and also makes a request to the server for a service worker file with the same name as the installed one (service-worker.js
in our case). It then compares those service work files for byte-equality, and if the one on the server is different, it begins the installation process in the background. Because our service worker include a manifest of the app assets to precache, which have hashes in their filenames, when the app files change, the compiled service worker will be recognized as new even though the service worker code didn’t change. This is also why there’s a new service worker update available every time there is a new app build deployed, as you’ve seen.The installation process in the background: when our service worker installs, it does some set-up chores including downloading and caching new app assets. This takes some time, which is why it’s done in the background and after the page loads to avoid interfering with the page load performance. Once its chores are done, the new service worker is now on deck behind the active one, waiting to take over. (The “active” service worker is the one that has control of network requests and can respond to requests with cached items). With no other interaction, the waiting service worker will take over after all the tabs of that app are closed. This update flow is designed this way because mixing the old assets the first service worker served with the new assets (and potentially different behavior) from the new service worker is a recipe for failure, and that’s also why the service “controller change” (a new one becoming active) shouldn’t be done without a reload.
We don’t currently forcibly reload the page when a waiting service is ready because that’s generally considered poor practice and has the potential for losing unsaved data (on a slow computer, it can take some time after loading the app for the update to be available), and instead show the prompt so that a new app version can be used before waiting for all the open tabs of the app to close.
Resources/further reading:
Beta Was this translation helpful? Give feedback.
All reactions