My progressive web app (PWA) is made up of various files like index.html
, manifest.json
, bundle.js
, and serviceWorker.js
. Updating the app involves uploading all these files to my host, which in my case is Firebase. I use firebase deploy
for this purpose.
Usually, the update process works smoothly: Existing users see the old version initially, but the new service worker automatically installs any updated files in the background. Then, when the user next opens the app, the new version activates and becomes visible.
However, there is a issue when a user accesses the app shortly after an update. It appears that the host delivers the new serviceWorker.js
but serves the old bundle.js
. Consequently, the service worker ends up caching the old bundle.js
, leading to users experiencing outdated functionality or even encountering a mix of new and old files.
I realize it could be argued that the hosting platform should update atomically, but since I have no control over Firebase, this seems unlikely. Moreover, given that browsers send independent fetch requests, there's no guarantee that all files returned will be consistent.
For reference, here is my serviceWorker.js
file. The cacheName
strings such as "app1-a0f43550e414"
are generated by my build pipeline. The hash value represents the latest version of bundle.js
, ensuring that the cache is only updated if the content of bundle.js
has changed.
"use strict";
const appName = "app1";
...
I've considered consolidating all my HTML, CSS, and JavaScript into a single large file to prevent inconsistencies. However, PWAs require separate supporting files such as the service worker, manifest, and icons that can't be bundled. Even if I bundle what I can, users may still end up with an outdated version of the bundle along with inconsistent supporting files. Additionally, I aim to reduce bundling and have more individual files in future updates for better granularity.
Another idea was to upload bundle.js
and other files under different filenames for each version. The service worker's fetch
function could hide the name change so that files like index.html
can still refer to it as bundle.js
. But this approach raises concerns about the initial loading of the app in a browser, as well as potential limitations on renaming certain key files like index.html
or manifest.json
.