Search code examples
javascriptbrowser-cacheservice-workerprogressive-web-appssw-toolbox

Best approach of Service Worker with query string version identifier on a heavy cached site


Story

I got a website using traditional browser cache, the site is heavy cached, up to 365 days for static content.

And to purge the cache after new version deployed, I am using a query string of version identifier like:

<script src="js/main.js?version=1.3.0"></script>

But for every upgrade of version, the load time is bad because browser need to download all the new contents when query string changed.


Situation

Now, we got Service Worker, and I've integrated it into my website. All is OK so far, the query string of version identifier still got using.

// simply cache all the static contents
global.toolbox.router.get('/', global.toolbox.networkFirst); 
global.toolbox.router.get(/(.js|.css|.png|.jpg|.json|.html)/, global.toolbox.fastest);

And the same behavior still presenting just like before SW integrated. And yet the upgrade is slow like it always do...


Question

And I am wondering if there are any better approach? which can do something like below and still keep the heavy cache mechanism (for old browsers):

  1. New version found
  2. Still use the old content of latest version,
  3. Under going fetch all the new content of new version,
  4. Next time user visit the site, they will use the latest version.

NOTE The goal it to load the site faster when a new version deployed


Solution

  • That's exactly how service workers' life cycle work. Let's see it in slow motion:

    First, you need to byte-level alter the service worker to force it to be updated: you could include the version of the application and store it in a variable var version = "1.0.0".

    Now the browser will find there is a new service worker and it will trigger its install event. In that handler, open your new cache (name it after your site version. For instance: "cache-v" + version) and fetch all the new resources.

    The new service worker won't get activated until the last tab controlled by the former service worker is closed. Once you close all the tabs and reopen the application, the new service worker will receive the activate event. In this handler you can delete the obsolete cache.

    And now your service worker is ready for fetching from the new cache.

    Key points here are:

    • To use a cache with a name derived from the version of the app.
    • To not use self.skipWaiting() during installation. This way you ensures the already installed service worker continue serving the current content.
    • To update the version in the service worker to summon the update machinery.