Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

service-worker `onupdatefound` not triggered on mobile

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

like image 878
LIIT Avatar asked Oct 26 '25 10:10

LIIT


1 Answers

There shouldn't be any difference in the service worker implementation in Chrome on Android and Linux that would account for one platform not having the updatefound event exposed on a service worker registration. (MDN isn't necessarily authoritative here.)

Whenever I've debugged this sort of unpredictable updates in the past, it's been due to interactions with the HTTP cache and the sw.js script. Can you check to see what Cache-Control headers you're using when you serve sw.js?

Also, you mention that you're using Workbox—you have access to a more advanced approach to checking for updated resources if that's the case. The workbox-broadcast-cache-update plugin (which is enabled by default if you're using workbox-sw's precache() method) can announce when a specific cached resource is updated, and then you can listen for that message on your page using the Broadcast Channel API. This allows you to only show your SnackBar when the most important resources change—like the HTML—rather than less important resources, like random images that might be precached.

like image 91
Jeff Posnick Avatar answered Oct 29 '25 01:10

Jeff Posnick



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!