Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workbox: the danger of self.skipWaiting()

I use Workbox to pre-cache assets required to render the app shell, including a basic version of index.html. Workbox assumes that index.html is available in cache, otherwise, page navigation fails because I have this registered in my Service Worker:

workbox.routing.registerNavigationRoute('/index.html');

I also have the self.skipWaiting() instruction in the install listener:

self.addEventListener('install', e => {
  self.skipWaiting();
});

As I understand it, there are 2 install listeners now:

  • One that's registered by Workbox for pre-caching assets (including index.html)
  • One that I registered manually in my Service Worker

Is it possible for self.skipWaiting() to succeed while Workbox's install listener fails? This would lead to a problematic state where assets don't get pre-cached but the Service Worker is activated. Is such a scenario possible and should I protect against it?

like image 685
Johnny Oshika Avatar asked Mar 26 '18 01:03

Johnny Oshika


1 Answers

I highly recommend "The Service Worker Lifecycle" as an authoritative source of information about the different stages of a service worker's installation and updating.

To summarize some info from that article, as it applies to your question:

  • The service worker first enters the installing phase, and however many install listeners you've registered, they will all get a chance to execute. As you suggest, Workbox creates its own install listener to handle precaching.

  • Only if every install listener completes without error will the service worker move on to the next stage, which might either be waiting (if there is already an open client using the previous version of the service worker) or activating (if there are no clients using the previous version of the service worker).

  • skipWaiting(), if you choose to use it, it will bypass the waiting stage regardless of whether or not there are any open clients using the previous version of the service worker.

  • Calling skipWaiting() will not accomplish anything if any of the install listeners failed, because the service worker will never leave the installing phase. It's basically a no-op.

The one thing that you should be careful about is using skipWaiting() when you are also using lazy-loading of versioned, precached assets. As the article warns:

Caution: skipWaiting() means that your new service worker is likely controlling pages that were loaded with an older version. This means some of your page's fetches will have been handled by your old service worker, but your new service worker will be handling subsequent fetches. If this might break things, don't use skipWaiting().

Because lazy-loading precached, versioned assets is a much more common thing to do in 2018, Workbox does not call skipWaiting() for you by default. It's up to you to opt-in to using it.

like image 110
Jeff Posnick Avatar answered Nov 10 '22 09:11

Jeff Posnick