Rimozione dei service worker che presentano errori

A volte viene eseguito il deployment di un service worker con bug, e poi ci sono dei problemi. Ad esempio, un service worker può essere analizzato al momento della registrazione e completare l'installazione con esito positivo. Tuttavia, la presenza di codice con bug in un evento fetch potrebbe far sì che non risponda alle richieste, generando una pagina vuota. Un'altra possibilità è che il markup della pagina venga memorizzato in modo aggressivo nella cache e un service worker restituisce solo risposte di markup obsolete da un'istanza Cache per le visite successive.

Un service worker può ritorcersi in vari modi, e questo è un problema spaventoso su un sito web di produzione. Anche così, non tutto è perduto. Ci sono modi per risolvere la situazione e tornare in pista.

Esegui il deployment di un service worker autonomo

Di solito basta il deployment di un service worker di base Service worker no-op che si installa e si attiva immediatamente senza un gestore di eventi fetch:

// sw.js

self.addEventListener('install', () => {
  // Skip over the "waiting" lifecycle state, to ensure that our
  // new service worker is activated immediately, even if there's
  // another tab open controlled by our older service worker code.
  self.skipWaiting();
});

self.addEventListener('activate', () => {
  // Optional: Get a list of all the current open windows/tabs under
  // our service worker's control, and force them to reload.
  // This can "unbreak" any open windows/tabs as soon as the new
  // service worker activates, rather than users having to manually reload.
  self.clients.matchAll({
    type: 'window'
  }).then(windowClients => {
    windowClients.forEach((windowClient) => {
      windowClient.navigate(windowClient.url);
    });
  });
});

Questo service worker si installerà e si attiverà immediatamente chiamando self.skipWaiting() nell'evento install. Facoltativamente, è possibile eseguire il deployment di codice aggiuntivo nell'evento activate per ricaricare forzatamente qualsiasi altra scheda aperta con un WindowClient controllato dal service worker.

È molto importante che un service worker autonomo non contenga alcun gestore di eventi fetch. Quando un service worker non gestisce le richieste, queste richieste passano attraverso il browser come se non fosse presente alcun service worker. Una volta eseguito il deployment di un service worker autonomo, è possibile risolvere il problema e eseguirne il deployment come aggiornamento in un secondo momento.

Questo approccio funziona in parte perché i browser presentano solide misure di protezione contro il posizionamento dei service worker nella cache HTTP e perché eseguono controlli byte per byte dei contenuti di un service worker per verificare la presenza di aggiornamenti. Queste impostazioni predefinite consentono di eseguire il deployment di una sostituzione automatica per un service worker con problemi, in modo da risolvere rapidamente il problema.

Ulteriori misure da adottare

Il deployment di un service worker autonomo dovrebbe essere sufficiente per neutralizzare uno con bug, ma è possibile adottare ulteriori misure se necessario.

E se non conosci l'URL del vecchio service worker?

A volte l'URL di un service worker installato in precedenza non è noto. Ciò potrebbe essere dovuto al fatto che il file è sottoposto al controllo delle versioni (ad esempio, contiene un hash nel nome del file). In questo caso può essere difficile eseguire il deployment di un service worker autonomo che corrisponda all'URL di ciascun service worker precedente che potrebbe essere registrato. Ciò va contro le best practice, poiché gli sviluppatori probabilmente non ricorderanno ogni hash per ogni versione del service worker di cui è stato eseguito il deployment.

Fortunatamente, viene inviata un'utile intestazione della richiesta HTTP con una richiesta di script del service worker: Service-Worker Sul server web, controlla questa intestazione e intercetta la richiesta per gestire invece un service worker autonomo. Il raggiungimento di questa azione dipende dal server web e dallo stack di backend utilizzato, quindi consulta la documentazione del linguaggio pertinente per sapere come fare.

Per quanto riguarda i deployment dei service worker futuri, utilizza i nomi degli asset senza versione (ad esempio, sw.js). Questo renderà le cose molto meno complicate in seguito.

Imposta un'intestazione Clear-Site-Data

Alcuni browser annullano la registrazione di tutti i Service worker per un'origine se È stata impostata l'intestazione della risposta Clear-Site-Data con valore 'storage'. Tuttavia, ci sono un paio di aspetti da tenere presenti quando si utilizza questo approccio:

  • Tieni presente che questa operazione cancellerà tutto lo spazio di archiviazione per l'origine associata. Sono inclusi localStorage, IndexedDB, sessionStorage e altri tipi di archiviazione (ma non la cache HTTP per l'origine).
  • Questa intestazione non è supportata in tutti i browser.

Poiché il supporto di questa intestazione non è totale, non è possibile fare affidamento solo su questa per risolvere il problema. Per questo motivo, ti consigliamo di considerare Clear-Site-Data come misura da adottare in aggiunta al deployment di un Service worker autonomo.

Il danno non è definitivo

Può essere spaventoso se l'esperienza utente viene interrotta da un service worker con bug, in particolare per siti web grandi e noti, ma il danno è temporaneo e reversibile.

Se è necessario eseguire il deployment di un service worker autonomo per risolvere la situazione, dedica del tempo a capire esattamente cosa non ha funzionato. In futuro, assicurati che un service worker gestisca solo le richieste previste. Esegui spesso test in fase di gestione temporanea ed esegui il deployment degli aggiornamenti solo in caso di sicurezza.