web-dev-qa-db-fra.com

Comment actualiser la page après une mise à jour de ServiceWorker?

J'ai consulté beaucoup de ressources sur les travailleurs des services:

Cependant, je ne saurai pas comment mettre à jour la page après l'installation d'un nouveau ServiceWorker. Quoi que je fasse, ma page est bloquée sur une ancienne version et seule une actualisation complète (Cmd-Shift-R) résoudra le problème. Aucune combinaison de 1) fermeture de l'onglet, 2) fermeture de Chrome ou 3) location.reload(true) servira le nouveau contenu.

J'ai un exemple d'application super simple principalement basé sur SVGOMG. Lors de l'installation, je mets en cache un ensemble de ressources à l'aide de cache.addAll(), et je fais également skipWaiting() si le numéro de version principale de la version actuelle ne correspond pas au numéro de la version active (basé sur une recherche IndexedDB):

self.addEventListener('install', function install(event) {
  event.waitUntil((async () => {
    var activeVersionPromise = localForage.getItem('active-version');
    var cache = await caches.open('cache-' + version);
    await cache.addAll(staticContent);
    var activeVersion = await activeVersionPromise;
    if (!activeVersion ||
      semver.parse(activeVersion).major === semver.parse(version).major) {
      if (self.skipWaiting) { // wrapping in an if while Chrome 40 is still around
        self.skipWaiting();
      }
    }
  })());
});

J'utilise un système d'inspiration semver dont le numéro de version majeur indique que le nouveau ServiceWorker ne peut pas être remplacé à chaud par l'ancien. Cela fonctionne du côté de ServiceWorker - une bosse de v1.0.0 à v1.0.1 provoque l’installation immédiate du serveur de travail sur une actualisation, alors que de v1.0.0 à v2.0.0, il attend que l’onglet soit fermé et rouvert avant d’être installée.

De retour dans le fil principal, je mets à jour manuellement ServiceWorker après l'enregistrement - sinon, la page ne reçoit jamais le mémo indiquant qu'une nouvelle version de ServiceWorker est disponible (curieusement, j'ai trouvé très peu de mentions à ce sujet dans la documentation ServiceWorker):

navigator.serviceWorker.register('/sw-bundle.js', {
  scope: './'
}).then(registration => {
  if (typeof registration.update == 'function') {
    registration.update();
  }
});

Cependant, le contenu qui est servi au fil principal est toujours bloqué sur une ancienne version de la page ("Ma version est 1.0.0"), que j'incrémente la version vers 1.0.1 ou 2.0.0.

Je suis un peu perplexe ici. J'espérais trouver une élégante solution semer-y à la gestion des versions ServiceWorker (d'où l'utilisation de require('./package.json').version), mais dans mon implémentation actuelle, l'utilisateur est toujours bloqué sur une ancienne version de la page, à moins qu'il ne soit actualisé manuellement ou effacé manuellement. toutes leurs données. : /

20
nlawson

Problème détecté - vous devez éviter les en-têtes de cache any du fichier ServiceWorker JS lui-même. La définition du cache sur max-age=0 a immédiatement résolu le problème: https://github.com/nolanlawson/serviceworker-update-demo/pull/1

Bravo à Jake Archibald de m'avoir mis au clair: https://Twitter.com/jaffathecake/status/689214019308224513

22
nlawson

Externe: arrêtez et désinscrivez un agent de service à l'aide de chrome: // serviceworker-internals / 

Interne du prestataire de services lui-même: https://developer.mozilla.org/en-US/docs/Web/API/Clients/claim et https://developer.mozilla.org/en-US/ docs/Web/API/ServiceWorkerGlobalScope/skipWaiting

3
gleb bahmutov

Dans Chrome Canary, vous pouvez effectuer toutes sortes de tâches de profilage et de gestion du personnel de service telles que désenregistrer, dans l'onglet Applications:

 enter image description here

Associez cela à chrome: // devices/pour déboguer avec votre périphérique physique.

1
Elise Chant