3

I have a web app that is working and relying on service workers to keep all the cached files in check and to make sure users are on the correct version of the app.

Our client is currently wanting the device to check for an update at specific points (When reopening the app) etc, as currently when you open the app it can take up to 5minutes before the device realises its on an outdated version.

Am I able to force the device to check the service worker for any new changes instead of waiting for the app to check for me?

Thanks!

Serge Stroobandt
  • 28,495
  • 9
  • 107
  • 102
Ryan Fisher
  • 113
  • 6

2 Answers2

2

There are two main points you should refine for instant update of your SW.

Shortly

  1. Call your sw.jsalso from more often visited pages than your app's index page.
  2. Utilize skipWaiting() method to activate your SW instantly.

In detail

1) navigator.serviceWorker.register method call

You should note that newer verison of the SW will only be checked by a navigator.serviceWorker.register() call.

And typically register() method will be called in one of your pages only. If that is the case, you should add that command to all of your pages. Because if user just opens another app without closing your PWA and then returns to your app after, say 2 hours, they will avoid the index page of the app where your register() call probably is.

So, my suggestion is to put it to many pages if not every. Downside is clients will make much more calls to sw.js. Upside is clients will retrieve last version of SW without losing time.

2) Activating service worker

Service Worker's activate event will be called when SW no longer has any active clients. So new version will be activated only after every instance of the app but one closed, and the remaining tab is refreshed/one tab re-opened. See quote from MDN about the matter:

..the new version is installed in the background, but not yet activated. It is only activated when there are no longer any pages loaded that are still using the old service worker. As soon as there are no more such pages still loaded, the new service worker activates.

And solution to this one would be using skipWaiting() method in conjunction with Clients.claim()

Usage example of those taken from MDN. Click to see more about it on that page:

self.addEventListener('install', function(event) {
  event.waitUntil(self.skipWaiting());
});
self.addEventListener('activate', function(event) {
  event.waitUntil(self.clients.claim());
});
Umur Karagöz
  • 2,970
  • 1
  • 19
  • 29
  • Thanks for the above, the thing is that the app is a single page webapp. So I do have the code running every load, the issue is that the service worker doesnt check immediatly on reopening - not sure if this could be due to the app shell being cached with the worker aswell? – Ryan Fisher Jan 29 '17 at 08:53
  • Okay, then section *#1* is not relevant to your situation. But have you implemented the solution on *#2*? If so, then there might be something else happening. When you update a cache, it will reinstall whole cache contents again. So, if you have a lot of files cached, and if client has a slow connection, it will take a while to download all the assets. And only after all the items have downloaded and inserted in cache will SW get activated. If none of above, I might take a look at your PWA if it is publicly available. – Umur Karagöz Jan 29 '17 at 09:17
0

Expiry directive in .htaccess on asset server

Make sure that the browser cache expiry directive set by the .htaccess file on your asset server is set to a really short duration or even to none as explained here. Failing to do so, will result in the browser not seeing any change for a while in the manifest.json, nor the service-worker.js.

Serge Stroobandt
  • 28,495
  • 9
  • 107
  • 102