I found some old topics about it but none really new, so I allow my self to start a new feed.
Right now I’m in an analysis phase, so I basically build a new app every 5 minutes and deploy it to test and I notice that most of the time my app scripts aren’t refreshed because the service-worker.js cache my main.js
Is it possible to set a max-age for that toolbox precache ?
I ask also myself how to handle this with live production app respectively how could a service-worker cached app notice that a new bundle was deployed on the server?
P.S.: I found the following really useful, in case you use firebase, you could set a cache-control expiracy, just add the following in your firebase.json
Tip: When testing Angular service workers, it’s a good idea to use an incognito or private window in your browser to ensure the service worker doesn’t end up reading from a previous leftover state, which can cause unexpected behavior.
@Tommertom yep it’s exactly what I do to test my pwa
any tips about the 2nd part of my question respectively what about live production? respectively how to let the app of the users notice there are updates we should replace what’s cached
In dev I would brute-force remove all service workers before registering the new one
navigator.serviceWorker.getRegistrations().then(function (registrations) {
for (let registration of registrations) {
console.log('registration', registration)
registration.unregister()
}
})
In production I would go for some references on websites (including angular) to notify change by amending a manifest file. (angular’s sw has its own way?)
I believe somewhere else it says that if the service-worker.js changes only slightly (a byte size change), the browser will refresh (after a refresh?). Next, I saw some implementations where the sw has a version for the cache and as such pulls a full refresh.
@Tommertom cool yes that helps, maybe that’s the way, having a version number (for example) or hash in service-worker.js in order to refresh the app when a new version would be published…that deserve a try, could be a quick win
On another note, I recently built a PWA with stencil. There the sw.js file is created automatically using workbox and has revisions for each file. So the sw.js is changed automatically when there is an update.
However I still had some caching issues and found that it helps if the index.html file also changes on each deploy. So now I also write the build date and time into a comment in index.html before each production build. Not sure if this is a good solution though.
I think one think I should do, since I’m using lazy loading is adding all *.js to the self.toolbox.precache of sw-toolbox which may help to detect when a new build is published
But I discovered that actually sw-toolbox and sw-precache are kind of deprecated. Looks like the team behind it have created and are actively support workbox which is even already use in the ionic-pwa-toolkit so no sure if I should not migrate that first because it might solve the preaching and new bundle question automatically (maybe?) https://developers.google.com/web/tools/workbox/modules/workbox-precaching
workbox sound definitely interesting and might be the way to solve the cache problem when updating the app and automatically
workbox-webpack-plugin could be chained to webpack and on each build will generate a new list of the resources to cache
but unfortunately can’t be used I did the migration, everything works fine … till I run a --prod build. workbox-webpack-plugin will generate a precache-hash.js file in the www/build folder containing the list of resource to cache, awesome, but problem is that ionic app-script try to minify all files under www/build and unfortunately fails on minifying that particular file
<script>
// Check that service workers are registered
if ('serviceWorker' in navigator) {
// Use the window load event to keep the page load performant
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
.then(() => console.log('service worker installed'))
.catch(err => console.error('Error', err));
});
}
</script>
Extra note: Just did a real test, sounds no that bad
I have built my app and then deploy it to my server
In an incognito browser I accessed my app, load everything and stuffs
In my code I added an alert, build it again and deployed it to the server
In the same browser as before which I didn’t close, I accessed my app again, I didn’t saw the alert. Was skeptical did it again and I saw the alert
For me even if I have to access my app twice, it displayed that the new bundle was successfully loaded, so it’s cool
Hi there, reedrichards What about the problem with the lazy loading pages that are not capable to auto-update when a new update was released. I am struggling with that, and I am feeling that may be a good idea to migrate from sw-toolbox to workbox, with workbox that not happens?. Thx in advance.
@brodriguezs can’t answer if it happens or not. generally speaking, sometimes it may still takes time to update the pages but I’ve the feeling that generally speaking it’s better with workbox than sw-toolbox
with workbox you will generate and deploy a list of hash of your bundled js, so if you use lazy loading it will contains x.js entries identified with hash. if you do a modification, then only the hash of the related js will be updated. this list helps workbox to notice which files have to be updated
I am facing the same issue, i always need to double cache clean on browser / mobile to get the newest version of my PWA.
I tried a lot of thing like :
service-worker.js
'use strict';
importScripts('./build/sw-toolbox.js');
self.toolbox.options.cache = {
name: 'ionic-cache',
maxEntries: 0,
maxAgeSeconds: 60
};
// pre-cache our key assets
self.toolbox.precache(
[
'./build/main.js',
'./build/vendor.js',
'./build/main.css',
'./build/polyfills.js',
'index.html',
'manifest.json'
]
);
// dynamically cache any other local assets
self.toolbox.router.any('/*', self.toolbox.networkFirst);
// for any other requests go to the network, cache,
// and then only use that cached resource if your user goes offline
self.toolbox.router.default = self.toolbox.networkFirst;
I just started using SwUpdate, part of angular/service-worker.
This will detect a new version of your PWA and let the user know it is ready to download it ( refresh ).
The alert can inform the user of any message you want as well.
This occurs after one load but it seems to take a couple of seconds.
Short usage:
ng add @angular/pwa --project app ( this will do most of the work )
in app.components.ts:
import { SwUpdate } from '@angular/service-worker';
constructor(
public updates: SwUpdate, ...
this.updates.available.subscribe(event => {
const changelog = event.available.appData['changelog'];
const message = changelog + " Click to refresh.";
if (confirm(message)) {
window.location.reload();
}
});
In ngsw-config.json:
"appData": {
"changelog": "Add your custom message here"
}