Based on my observation that both the PWA client and the browser version do not update, for the last several nights I was digging into why and how to fix it. Now I have fixed and localhost served tested code that works well.
I plan to commit the code to my fork of newspeak; I suppose the best way to communicate this would be via a pull request from my fork of the newspeak github repo, let me know if otherwise. I suppose I will send the pull request anyway, you can always reject it or ask me for changes.
I am not sure where to start describing it, so maybe I just paste here part of the text I plan to place to the commit that should end up in the pull request. It is long, and you will see it in the pull request, but here it is ahead of time, if there is something I need to clarify:
TL;DR:
- This commit fixes the failure of the Newspeak service worker (sw.js) to
update its caches. This issue caused the Newspeak PWA client app on the user's
device to never pick up server updates, notably the changed HopscotchWebIDE.vfuel.
- The changed files are sw.js, index.html, build.sh; there is a new script 'increase-pwa-version.sh'
called from 'build.sh'.
- Apart from fixing the end-user experience, this change also touches Newspeak development
(without any changes in the developer's workflow), as running '. ./build.sh' now changes
the variable pwaVersion in 'sw.js'
- How to test this change:
- Server / build
- Get the latest version and make sure webIDE/index.html is copied to the webIDE directory
where Newspeak is served locally for
https://localhost:8080/webIDE,
or for
https://newspeaklanguage.org/webIDE.
I am serving from the git version of webIDE, so I do not have to copy anything.
- Run . ./build.sh as normally.
- Make sure the updated webIDE/sw.js is copied into the webIDE directory where Newspeak is served.
I am serving from the git version of webIDE, so I do not have to copy anything.
- PWA Client / browser
- You do NOT have to do anything, the versioned sw.js should now be installed,
and use its versioned cache. But if you want to check:
- In Browser, navigate to
https://localhost:8080/webIDE,
or
https://newspeaklanguage.org/webIDE.
- Open the PWA
- In both browser and PWA, if you press F12 to debug (Chrome) and look at:
Application -> Storage -> Cache Storage.
you should see a versioned cache number, such as 'newspeak-ide-cache-version-13'.
- Every time a new server version is build and the new build deployed,
you should see a new cache version on the client PWA or browser,
such as 'newspeak-ide-cache-version-14'.
Motivation for change:
- 'Before this change': After a new Newspeak version deployment on
https://newspeaklanguage.org/webIDE, the PWA client app on the user's device
did not update even after multiple launches, unless a manual cache clean was performed.
I had the same experience (the PWA client not updating) with the webIDE server
running on localhost, and the PWA client created from it.
In fact, even the in-browser running webIDE did not update after server deployment.
- Having looked into how service workers function, it seems clear that
the mechanism that causes the service worker update on the user's device
(changing some bits) was never triggered. As a result, the service worker caches are never automatically
updated, causing, among other things, the same (old) HopscotchWebIDE.vfuel to be used after server update.
Service worker lifecycle - summary
- From
https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Tutorials/CycleTracker/Service_workers:
- Once the PWA is installed on the user's machine, THE ONLY WAY to inform
the browser that there are updated files to be retrieved is to change
the service worker (this file, sw.js) on the server.
- Corollary: The only way for a PWA website to force an update of the service worker
is to make a bit-change on the server's service worker (the sw.js).
Such enforced update of the service worker, causes the browser to call a one-time 'install' and 'activate' on the
service worker, which the service worker can use to delete old caches and cache the new assets.
Changed files in more detail:
- index.html
- moved caching of assets (cache.addAll) to the 'install' event in sw.js
- added catching errors during serviceWorker.register
- sw.js
- almost complete rewrite, although keeping the basics of using cache-first strategy
(assuming used to lighten load on the server)
- added a version number which should be changed on every deployment,
to support the reinstall of the service worker on the client PWA browser.
This number is increased automatically, during running each '. ./build.sh'
by calling the added 'increase-pwa-version.sh'
- 'const pwaVersion = 12;'
- added a versioned cache name
- 'const pwaCacheName = 'newspeak-ide-cache-version-' + pwaVersion;'
- added a full list of assets
- 'const pwaAppResources = [ .. see code .. ];'
- added processing in the 'install' event:
- all assets listed in 'pwaAppResources' are added to the NEW cache version 'pwaCacheName'
- added processing in the 'activate' event:
- OLD caches are deleted
- modified processing in the 'fetch' event
- In principle, this remains the cache-first fetching, but error checking was added etc
- Assets not in 'pwaAppResources' would still cache here from network
- build.sh
- added call to 'increase-pwa-version.sh' which increases version number in sw.js by 1, example
- 'const pwaVersion = 12;' => 'const pwaVersion = 13;'
- increase-pwa-version.sh
- a simple sed script that edits sw.js and increases version number by 1.