service-worker `onupdatefound` not triggered on mobile

Viewed 4142

Bellow is how I register my serviceworker :

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    function updateOnlineStatus() {
      SnackBar.show({
        text: navigator.onLine ? onlineMsg : offlineMsg,
        backgroundColor: '#000000',
        actionText: close,
        actionTextColor: '#d2de2f',
        customClass: 'custom-snackbar',
      });
    }
    window.addEventListener('online', updateOnlineStatus);
    window.addEventListener('offline', updateOnlineStatus);
    navigator.serviceWorker.register('sw.js').then((reg) => {
      reg.onupdatefound = () => {
        const installingWorker = reg.installing;
        installingWorker.onstatechange = () => {
          switch (installingWorker.state) {
            case 'installed':
              if (navigator.serviceWorker.controller) {
                SnackBar.show({
                  text: refreshMsg,
                  backgroundColor: '#000000',
                  actionText: refresh,
                  actionTextColor: '#d2de2f',
                  onActionClick: () => { location.reload(); },
                  customClass: 'custom-snackbar',
                });
              } else {
                console.info(availableMsg);
              }
              break;
            case 'redundant':
              console.info(redundantMsg);
              break;
            default:
              break;
          }
        };
      };
    }).catch((e) => {
      console.error(errorMsg, e);
    });
  });
}

This service-worker is generated during build by Workbox.

I'm a bit worried because these notifications are displayed on my computer (ubuntu + chrome 59.0.3071.115) however never on my mobile (android 6.0.1 + chrome 59.0.3071.125)

After analyzing with remote debugging feature, it looks like onupdatefound is never triggered on my mobile.

I feel very bad about UX, thinking about visitors on mobile that wouldn't know that a new version of website is pending ...

Any suggestion or advice will be appreciated


Edit 1 : I've found more details on "Browser Compatibility" section of this webpage : https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/onupdatefound. It looks like support of this feature by Chrome for Android is unknown.

Do you guys have a kind of fallback / workaround when browser do not support onupdatefound event ?


Edit 2 : In response to Jeff,
sw.js header is managed in .htaccess file :

<Files sw.js>
  Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
  Header set Pragma "no-cache"
  Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</Files>

which produces :

accept-ranges: bytes
cache-control: max-age=0, no-cache, no-store, must-revalidate
content-encoding: br
content-language: fr-FR
content-length: 1636
content-type: application/javascript; charset=utf-8
date: Fri, 21 Jul 2017 13:04:06 GMT
expires: Wed, 11 Jan 1984 05:00:00 GMT
last-modified: Tue, 18 Jul 2017 02:58:30 GMT
pragma: no-cache

Regarding workbox fine tuning you suggest, I didn't find time to dig in yet so i'm using the easy workbox-build in a gulp file. But I hopefully will :)

// Service Worker generation
gulp.task('bundle-sw', gulp.series('generate-sitemap', () => {
  return wbBuild.generateSW({
    globDirectory: gulpOutputDir,
    swDest: `${gulpOutputDir}/sw.js`,
    globPatterns: ['**/*.{html,png,xml,css,ico,txt,json,svg,js,map,gif,jpeg,jpg,bmp,cur,webp,woff2}'],
    skipWaiting: true,
    clientsClaim: true,
  })
  .then(() => {
    console.warn('Service worker generated.');
  })
  .catch((err) => {
    console.error(`[ERROR] This happened: ${err}`);
  });
}));

Do you think it could be caused by skipWaiting: true ?


Edit 3 : Trying with BroadcastChannel

navigator.serviceWorker.register('/sw.js').then((reg) => {
  console.log('test');
  const updateChannel = new BroadcastChannel('precache-updates');
  updateChannel.addEventListener('message', event => {
    console.log(`Cache updated: ${event.data.payload.updatedUrl}`);
  });
}).catch((e) => {
  console.error(errorMsg, e);
});

Even if test is outputed in log on Chrome, mobile, or firefox, update messages are only thrown on Chrome

2 Answers
Related