2017-07-18 1 views
1

Bellow est comment enregistrer mon serviceworker:serviceworker `onupdatefound` ne se déclenche pas sur le mobile

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); 
    }); 
    }); 
} 

Cette serviceworker est générée lors de la construction par Workbox.

Je suis un peu inquiet parce que ces notifications sont affichées sur mon ordinateur (ubuntu + chrome 59.0.3071.115) mais jamais sur mon portable (android 6.0.1 + chrome 59.0.3071.125)

Après avoir analysé avec fonction de débogage à distance, il ressemble à onupdatefound est jamais déclenché sur mon mobile.

Je me sens très mal à UX, en pensant à des visiteurs sur mobile qui ne connaîtraient pas une nouvelle version du site est en cours ...

Toute suggestion ou des conseils seront appréciés


Edit 1: J'ai trouvé plus de détails sur la section «Compatibilité du navigateur» de cette page Web: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/onupdatefound. Il semble que la prise en charge de cette fonctionnalité par Chrome pour Android soit inconnue.

Avez-vous les gars une sorte de solution de rechange/contournement lorsque le navigateur ne supporte pas onupdatefound événement?


Edit 2: En réponse à Jeff,
sw.js tête est géré .htaccess fichier:

<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> 

qui produit:

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 

vous En ce qui concerne workbox réglage fin suggérez, je n'a pas trouvé le temps de creuser encore si j'utilise le workbox-build facile dans un fichier de gulp. Mais je l'espérons :)

// 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}`); 
    }); 
})); 

Pensez-vous que cela pourrait être causé par skipWaiting: true?


Edit 3: Essayer avec 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); 
}); 

Même si test est dans le journal sur outputed Chrome, mobile ou firefox, mettre à jour les messages ne sont jetés sur Chrome

+0

https://developers.google .com/web/fundamentals/instant-and-offline/service-worker/cycle de vie # handling_updates Vous voudrez peut-être revoir votre observateur après avoir consulté les documents. –

Répondre

1

Il ne devrait pas être une différence dans l'implémentation de l'agent de service dans Chrome sur Android et Linux qui représenterait une plate-forme ne présentant pas l'événement updatefound exposé sur un enregistrement de travailleur de service. (MDN ne fait pas forcément autorité ici.)

Chaque fois que j'ai débogué ce genre de mises à jour imprévisibles dans le passé, cela est dû à des interactions avec le cache HTTP et le script sw.js. Pouvez-vous vérifier pour voir quels en-têtes Cache-Control vous utilisez lorsque vous servez sw.js?De plus, vous mentionnez que vous utilisez Workbox - vous avez accès à une approche plus avancée pour vérifier les ressources mises à jour si c'est le cas. Le plugin workbox-broadcast-cache-update (qui est activé par défaut si vous utilisez la méthode precache() de workbox-sw) peut annoncer quand une ressource spécifique mise en cache est mise à jour, puis vous pouvez écouter ce message sur votre page en utilisant l'API Broadcast Channel. Cela vous permet d'afficher uniquement votre SnackBar lorsque les ressources les plus importantes changent, comme le HTML, plutôt que des ressources moins importantes, comme des images aléatoires qui peuvent être préchargées.

+0

Merci d'avoir pris le temps! J'ai édité OP avec plus de détails liés à vos observations – LIIT

+1

Ni 'skipWaiting' ni' clientsClaim' ne devraient empêcher l'événement 'updatefound' d'être déclenché. Si vous utilisez 'workbox-build', alors le fichier' sw.js' généré recevra les mises à jour de l'API de Broadcast Channel "gratuitement". Ecoutez simplement les mises à jour de vos pages client sur le canal 'precache-updates'. Voir https://workboxjs.org/reference-docs/latest/module-workbox-sw.WorkboxSW.html#properties –

+0

J'ai appliqué vos suggestions (modifier 3). Malheureusement, il ne fonctionne toujours pas sur mobile ou Firefox, mais il fonctionne toujours sur le chrome de PC. Je suis vraiment confus :(Mais merci pour votre aide de toute façon! – LIIT

1

Comme vous le suspectiez, le problème ne venait pas du Service Worker.

Je suis parti de zéro et j'ai essayé d'identifier l'origine de ce problème en ajoutant du code morceau par morceau jusqu'à ce que plus aucun événement ne soit exposé. Je l'ai compris: c'était à cause d'une boucle "coûteuse" utilisée dans une animation three.js.

Après avoir mis ce morceau de code dans un travailleur, ma page est maintenant capable d'attraper ces événements sur mobile ou Firefox et la notification de l'utilisateur fonctionne très bien!

À propos du fait confus qu'il travaillait sur la version de bureau de Chrome, je suppose que c'est parce qu'il doit prendre en charge le multithreading ...

Merci encore pour votre aide :)

+0

Cela semble être un bug Avez-vous signalé cela à l'équipe de chrome? –