I have a single page application and need the clients to be on the latest version. Caching is aggressive so waiting for them to invalidate isn't feasible.
Is there a way to tell the client to look at a resource (say something like build.txt) and if that resource contains a build number greater than the current one loaded, invalidate the cache and refresh?
I have a single page application and need the clients to be on the latest version. Caching is aggressive so waiting for them to invalidate isn't feasible.
Is there a way to tell the client to look at a resource (say something like build.txt) and if that resource contains a build number greater than the current one loaded, invalidate the cache and refresh?
Share Improve this question asked May 30, 2019 at 0:38 David AlshDavid Alsh 7,6858 gold badges43 silver badges79 bronze badges 6- I had a middleware that attached the current git mit ID as a header with all API responses. If it changed, I did a full reload. Perhaps something along those lines? – ceejayoz Commented May 30, 2019 at 0:42
-
Just using
location.reload()
? – David Alsh Commented May 30, 2019 at 0:49 - In my case, yes, as we were using versioning on CSS/JS/image assets. – ceejayoz Commented May 30, 2019 at 0:51
-
@DavidAlsh
location.reload()
will reload the main page, but not invalidate the cache of all resources that it loads, like CSS and JS files. – Barmar Commented May 30, 2019 at 0:53 - I don't think there's any good way to force clients to clear their caches automatically. You should reduce the cache lifetime in advance of the update. – Barmar Commented May 30, 2019 at 0:54
2 Answers
Reset to default 5As this question has been tagged with progressive-web-apps
I'm going to assume that it's installing a service-worker, which is what is aggressively caching the resources.
This post runs though showing a "new version available" popup for PWAs - even if it's not the particular behaviour you want, it explains a lot about how service-workers get updated.
This question/answer also goes over how often the service-worker is checked for updates.
This question/answer goes over pros/cons of always using skipWaiting
to keep the client immediately up to date.
Edit: If you're just dealing with regular HTTP Cache, try using location.reload(true)
(reload with the forcedReload
flag set) when you detect that there's a newer version on the server. In the past I've done this by putting the release number into the js code at build/release time, and having the server add its release number to every response as a header. A simple pare of the values after an ajax call can confirm whether the ui and server release numbers match and take action when they don't.
Credit to Jono Job for helping me achieve this solution.
What I ended up doing was the following:
In my build pipeline I added the following two lines before the client build
- sed -i -e "s/{{build-number}}/${CI_COMMIT_SHORT_SHA}/g" ./src/environments/environment.prod.ts
- echo $CI_COMMIT_SHORT_SHA > ./src/assets/build.txt
The first line pushes the mit hash into the piled javascript bundle, the second creates a text file with the mit hash as the content.
I then set up an Angular service which uses the http client to poll the text file which contains the mit hash. It checks to see if the hash in the text file is different to the hash loaded from the javascript bundle.
The theory here is that the Javascript bundle can be cached, but the http request to fetch the build.txt file will not be. Allowing me to inspect a difference between the build hashes stored in the two.
If the service detects a difference in builds, it would project a prompt to the user notifying them of an update which, upon clicking, would refresh the page.
Refreshing is done using window.location.reload(true)
. TypeScript tells me the parameter is deprecated, though it still works.
Here's a gist of the aforementioned Angular service: https://gist.github./alshdavid/032ea535f222646dc74420e20b28faa1
In my APM, I can see that within a couple of hours of pushing an update, everyone client has been updated to the latest version.
So it probably works.