In this article, I outline our approach to solving the problem of people not "getting" the latest version of our SPA.
A single-page application ...
For further actions, you may consider blocking this person and/or reporting abuse
We have netlify hit a route on our backend that then in turn sends a special message via MQTT to all currently active users, which causes an "An update is ready, please click to load the new version" message to appear at the bottom of their screen.
Works great, super painless thanks to that netlify webhook
Nice. Did you already have the backend -> frontend communication set up, or did you add it specifically for the purpose of the update notice?
As mentioned in the article, it seemed overkill to us to add a completely new communication system just for this purpose.
How did you solve the issue of excluding the index.html file from service-worker for having the new index.html all the time directly from the server and not form service-workers or disk cache. Also if possible could you share the function isNewerVersionAvailable()
Hi,
This app did not make use of service workers, so we did not have to implement any workarounds. Since the headers on Cloudfront were set so that html files were never cached, there were never any cache-related problems.
I have since changed jobs so I no longer have access to the source code, but the logic was something like:
Was the edge-case of the first request being a new version considered? Seems like a user could potentially miss out on a notification for an entire version if their first page load is within the 10 minute interval of a new version being deployed.
I suppose a workaround could be just setting
oldSource
ASAP after first page load which cuts the edge-case window down drastically.Thanks. Just one question why didn't you considered calling some other smaller file's response headers time stamp by fetching that one. That could have saved some data per request.
The fact is that our HTML file was already rather small (2.57kb gzip), so while fetching for example just file headers would have been less expensive in terms of bandwidth, I think we were rather happy with that approach. If I were to do it again, I would test the headers approach and go with that if it was equally reliable.
I liked your considerations and approach. But isn't this is something that is already solved by a service worker? Events for update notifications and triggering of updates.
Hey Lars, thanks for the feedback.
As far as I am aware, a service worker checks for the new version availability on page load, but we needed the checks for people who were idle, or who were just browsing the app without refreshing.
Additionally, even if it would technically do what we needed it to, we were not making use of the service worker in that particular spa, so adding an additional script just for the update detection mechanism did not seem worth it.
Lastly, we also support IE11 on our app, so that was taken into consideration as well.
I see. What about this issue, how are you going to handle that?
Registered service workers have an
update
method to check for updates manually.Actually, in this case, we actually prefer to notify the user about the update in every tab.
It would be bad to not show the notification in every tab (we ideally don't want users to run the old version in some of them), but we also can't refresh all tabs at once (some of them might have data that the user does not want to lose).
I hope that makes sense, but let me know if I am missing your point.
What do you do with problematic extensions that modifies content on the fly? Users will see a 'Reload to update' notification every tick of the timer. We are currently facing this problem.
Hi,
We did not have any reports of this. How are you fetching the HTML? Are you relying on innerHTML initially? Most of the extensions will mess with that, but not with the response of the network request itself, so if you only rely on what fetch gives you, I believe you should be fine in most cases.
If that's still a problem, you could rely on the "last-modified" header instead. We serve this app via S3 + CloudFront, and it sends the last-modified header. You can then access it and compare that instead of the whole HTML.