Modifiche a cache.addAll() e importScripts() disponibili in Chrome 71

Gli sviluppatori che utilizzano i service worker e l'API Cache Storage devono prestare attenzione a due piccole modifiche implementate in Chrome 71. Entrambe le modifiche rendono l'implementazione di Chrome più in linea con le specifiche e con altri browser.

Impedendo l'importazione asincrona di script()

importScripts() indica allo script del tuo worker di servizio principale di mettere in pausa l'esecuzione corrente, scaricare codice aggiuntivo da un determinato URL ed eseguirlo fino al completamento nell'ambito globale corrente. Al termine, lo script del worker di servizio principale riprende l'esecuzione. importScripts() è utile quando vuoi suddividere lo script del tuo service worker principale in parti più piccole per motivi organizzativi o importare codice di terze parti per aggiungere funzionalità al tuo service worker.

I browser tentano di mitigare i possibili problemi di prestazioni di "scarica ed esegui del codice sincrono" memorizzando automaticamente nella cache tutto ciò che viene recuperato tramite importScripts(), il che significa che dopo il download iniziale, l'esecuzione del codice importato comporta un overhead molto ridotto.

Tuttavia, affinché funzioni, il browser deve sapere che non verrà importato alcun codice "a sorpresa" nel servizio worker dopo l'installazione iniziale. In base alla specifica del worker di servizio, la chiamata a importScripts() dovrebbe funzionare solo durante l'esecuzione sincrona dello script del worker di servizio di primo livello o, se necessario, in modo asincrono all'interno del gestore install.

Prima di Chrome 71, la chiamata di importScripts() in modo asincrono al di fuori dell'handler install andava bene. A partire da Chrome 71, queste chiamate generano un'eccezione di runtime (a meno che lo stesso URL non sia stato precedentemente importato in un gestore install), in linea con il comportamento in altri browser.

Invece di un codice come questo:

// This only works in Chrome 70 and below.
self.addEventListener('fetch', event => {
  importScripts('my-fetch-logic.js');
  event.respondWith(self.customFetchLogic(event));
});

Il codice del tuo worker di servizio dovrebbe avere il seguente aspetto:

// Move the importScripts() to the top-level scope.
// (Alternatively, import the same URL in the install handler.)
importScripts('my-fetch-logic.js');
self.addEventListener('fetch', event => {
  event.respondWith(self.customFetchLogic(event));
});

Ritiro degli URL ripetuti passati a cache.addAll()

Se utilizzi l'API Cache Storage insieme a un servizio worker, in Chrome 71 è presente un'altra piccola modifica per allinearsi alla specifica pertinente. Quando lo stesso URL viene passato più volte a una singola chiamata a cache.addAll(), la specifica prevede che la promessa restituita dalla chiamata debba essere rifiutata.

Prima di Chrome 71, questo non veniva rilevato e gli URL duplicati venivano effettivamente ignorati.

Uno screenshot del messaggio di avviso nella console di Chrome
A partire da Chrome 71, visualizzerai un messaggio di avviso registrato nella console.

Questo logging è un preludio a Chrome 72, dove, anziché un semplice avviso registrato, gli URL duplicati causeranno il rifiuto da parte di cache.addAll(). Se chiami cache.addAll() all'interno di una catena di promesse passata a InstallEvent.waitUntil(), come è prassi comune, il rifiuto potrebbe causare l'errore di installazione del service worker.

Ecco come potresti riscontrare problemi:

const urlsToCache = [
  '/index.html',
  '/main.css',
  '/app.js',
  '/index.html', // Oops! This is listed twice and should be removed.
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('my-cache').then(cache => cache.addAll(urlsToCache))
  );
});

Questa limitazione si applica solo agli URL effettivi trasmessi a cache.addAll() e la memorizzazione nella cache di quelle che risultano essere due risposte equivalenti con URL diversi, come '/' e '/index.html', non attiverà un rifiuto.

Testa l'implementazione del tuo service worker su larga scala

A questo punto, i Service worker vengono ampiamente implementati in tutti i principali browser "evergreen". Se testi regolarmente la tua app web progressiva su diversi browser o se hai un numero significativo di utenti che non utilizzano Chrome, è probabile che tu abbia già rilevato l'incongruenza e aggiornato il codice. Tuttavia, nell'eventualità in cui tu non abbia notato questo comportamento in altri browser, volevamo segnalare la modifica prima di cambiare il comportamento di Chrome.