hashcoder
hashcoder

Reputation: 520

Service worker cache update issue - EDGE browser - sw-precache

I'm working on an AngularJS application where we have implemented offline capability using Service Worker Caching (using sw-precache). Once the user loads the page, all the assets (configured in sw.js file) will be downloaded and cached by registered Service Worker. (Service worker will create a map with the key as url of the file + unique hash of file). Next time onwards the request for any of these assets will be served from cache if the cache Id matches. If any file has changed on the server, the hash of the file changes, so the request will not be served from the cache, but from the server. More details on this can be found here

https://medium.com/@Huxpro/how-does-sw-precache-works-2d99c3d3c725

View of Service Worker Cache:

enter image description here

It is working fine, but now we have to support Edge browsers as well, where caching is not working as expected. Whenever there is a new version of the web application, Edge doesn't update the cache as expected. I can see the hash has been updated in the cache, but the content is still the old. User has to refresh the page multiple times so that content changes.

We generate the sw.js using sw-precache via grunt task.

Gruntfile.js

swPreachce: {
    
    build: {
        options: {
          // baseDir: 'app/',
          cacheId: 'etags', // same as name in package.json
          workerFileName: 'app/dist/sw.js',
          verbose: true,
          stripPrefix: 'app/dist/',
          importScripts: ['serviceworker-cache-polyfill.js', 'sw-resource.js'],
          templateFilePath: 'app/sw-template.tmpl',
          navigateFallback: '/index.html',
          maximumFileSizeToCacheInBytes: 6291456, // 6MB, default limit is 2MB but bower.js and cust_pdfmaker.js are bigger than that
          staticFileGlobs: [
            'app/dist/index.html',
            'app/dist/manifest.json',
            'app/dist/offline.html',
            'app/dist/serviceworker-cache-polyfill.js',
            'app/dist/sw-resource.js',
            'app/dist/fonts/**/*.{woff,woff2,ttf,svg,eot}',
            'app/dist/form-builder/**/*.html',
            'app/dist/images/**/*.{gif,svg,png,jpg,jpeg}',
            'app/dist/lang/**/*',
            'app/dist/protected/**/*',
            'app/dist/proxies/**/*.json',
            'app/dist/scripts/**/*.{js,json}',
            'app/dist/styles/**/*.css',
            'app/dist/urlPattern/**/*.json',
            'app/dist/views/**/*.{html,json}'
          ]
        }
}

The JS file which registers the Service Worker.

function registerSW() { navigator.serviceWorker.register('sw.js') .then(onRegistration) .catch(function (err) { // registration failed Logger.error('ServiceWorker registration failed: ', err); }); }

// tracking registartion progress
function onRegistration(registration) {
  if (registration.waiting) {
    ETAGSLogger.log('waiting', registration.waiting);
    registration.waiting.addEventListener('statechange', onStateChange('waiting'));
  }

  if (registration.installing) {
    ETAGSLogger.log('installing', registration.installing);
    registration.installing.addEventListener('statechange', onStateChange('installing'));
  }

  if (registration.active) {
    ETAGSLogger.log('active', registration.active);
    registration.active.addEventListener('statechange', onStateChange('active'));
  }
}

In case of Chrome, when there is an app update, the auto-refresh condition becomes true and the page reloads, and the new file changes are reflected. But in Edge this doesn't become true, and the page never reloads.


function onStateChange(from) {

      return function (e) {
        ETAGSLogger.log('statechange', from, 'to', e.target.state);
        
        // When there is already a serviceworker and a new version is deployed
        // from === 'active' and it will go to 'activated' or 'redundant' 
    // (in case it has been replaced by a newer version)
        // Here we want to auto-refresh to provide the latest resources from the cache.
        if (from === 'active' && (e.target.state === 'activated' || e.target.state === 'redundant')) {
          $window.location.reload();
        }
      }
    }

What I have observed in Edge is whenever I close the browser, the registered Service Worker will get unregistered, where as in Chrome it just become inactive (PFA).

Chrome

enter image description here

Edge:

enter image description here

Did any one else face the issue in Edge ? I know I can fix this by renaming the filenames in the Grunt build process ( appending the hash to css, js and htmls), but renaming the template files will be tough since they are being referred from all over the code. I heard about ETag, not sure generating a new ETag for the newer versions will fix this. Please advice if there is a better way to force a reload on Edge.

Upvotes: 0

Views: 34

Answers (0)

Related Questions