Polymer / polymer-starter-kit

A starting point for Polymer apps

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to update files cached by service worker?

davidmaxwaterman opened this issue · comments

I have an app that was based on psk, but I am having trouble updating the app when I have deployed new source files.
I have it installed on my Nexus 5 and the only way I seem to force it to update is by going to chrome://serviceworker-internals and unregistering the SW. I have tried reloading the app by dragging down and getting the reload icon, but that doesn't seem to do the trick.
Any pointers would be welcome.

Oh, I should also point out that, from what I read, the service worker would first serve the cached files and get new ones from the network, then the cache would be updated for the next load...but that doesn't seem to be the case.

polymer build internally uses sw-precache to generate a service worker which contains hashes of the output files, for example:

var precacheConfig = [["index.html","97f753b9a712d6873e321c7f29adf9ad"], /* ... */];

This hash changes when the source changes, so the resulting SW will be byte-different than the previous SW. When this happens, the SW will update the precached assets and they will be available on the next page load (thus why some sites use a "refresh to update" prompt).

Like other files, the SW script is subject to disk-caching by the browser. So, it's recommended that you set a Cache-Control: max-age=0 HTTP header on service-worker.js (though not required, if you're okay will serving a stale site).

Further reading: https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle

It would be really awesome if the PSK were to include code that shows an implementation of a 'new version available. Update [yes][not]' toast, and associated sw code.

For reference, here's how the Polymer docs site creates that toast: https://github.com/Polymer/docs/blob/master/app/js/app.js#L130

The implementation in the link does not work for the PSK..

I've copied the code and replaced the service worker registration lines in index.html with the ones from the link, and replaced the toast messages and console.log these instead, since there is no material toast in the psk...:

if ('serviceWorker' in navigator) {
  console.log("Browser Supports Service Worker");
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('service-worker.js', {
     scope: Polymer.rootPath,
   }).then(function(registration) {
      registration.onupdatefound = function() {
        // The updatefound event implies that registration.installing is set; see
        // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event
        const installingWorker = registration.installing;
        installingWorker.onstatechange = function() {
          switch (installingWorker.state) {
            case 'installed':                    
              if (!navigator.serviceWorker.controller) {
                //window.showToast('Service Worker installed!...
                console.log("Service Worker is installed!");
              }
              break;
              
            case 'redundant':
              console.log("The installing service worker became redundant.");
          }
        };
      };
    }).catch(function(e) {
      console.log("Service worker registration failed:", e);
    });
    // Check to see if the service worker controlling the page at initial load
    // has become redundant, since this implies there's a new service worker with fresh content.
    if (navigator.serviceWorker.controller) {
      navigator.serviceWorker.controller.onstatechange = function(event) {
        if (event.target.state === 'redundant') {
          console.log("Service Worker is redundant. New content is available, refresh to see the changes!")
          // window.showToast('Site updated. Refresh this page to see the latest content.');
        }
      };
    }
  });
}

I can do everything (change e.g. service worker cache id and rebuild it), all the messages don't log but the first ("Browser Supports Service Worker").
But when i hit update service worker in dev tools it is logging...("Service Worker is installed")

There are syntax errors in that code snippet, which are apparent if you use GitHub markdown code blocks:

      if ('serviceWorker' in navigator) {
        console.log("Browser Supports Service Worker");
        window.addEventListener('load', function() {
          navigator.serviceWorker.register('service-worker.js', {
           scope: Polymer.rootPath,
         }).then(function(registration) {
            registration.onupdatefound = function() {
              // The updatefound event implies that registration.installing is set; see
              // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event
              const installingWorker = registration.installing;
              installingWorker.onstatechange = function() {
                switch (installingWorker.state) {
                  case 'installed':                    
                    if (!navigator.serviceWorker.controller) {
                      //window.showToast('Service Worker installed! Pages you view are cached for offline use.');
                      console.log("Service Worker is installed!
                    break;

                  case 'redundant':
                    console.log("The installing service worker became redundant.");
                }
              };
            };
          }).catch(function(e) {
            console.log("Service worker registration failed:", e);
          });

          // Check to see if the service worker controlling the page at initial load
          // has become redundant, since this implies there's a new service worker with fresh content.
          if (navigator.serviceWorker.controller) {
            navigator.serviceWorker.controller.onstatechange = function(event) {
              if (event.target.state === 'redundant') {
                console.log("Service Worker is redundant. New content is available, refresh to see the changes!")
                // window.showToast('Site updated. Refresh this page to see the latest content.');
              }
            };
          }
        });
      }

Sorry, updated the code block, it was a copy paste error.
Even without the mistakes, the behaviours is like described above.

But i've found out that its not an issue with the service worker registering:
For those hosting on Firebase, the Cache-Control header cache-control:max-age=3600is set to one hour, so for apps in development you can use this snippet inside your firebase.json's hosting Object to disable caching for the service worker at all:

    "headers": [{
      "source" : "service-worker.js",
      "headers" : [{
        "key" : "Cache-Control",
        "value" : "max-age=0"
      }]
    }]

In a production environment, however, one should rethink the importance of the app's up-to-dateness for the sake of LIGHTSPEED page load times and adjust it back to one hour ;-)

thx @keanulee for helping anyway, not learned markdown so far!