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

Gli sviluppatori che utilizzano i service worker e l'API Cache Storage dovrebbero prestare attenzione in fase di implementazione in Chrome 71. Entrambe le modifiche allineano maggiormente l'implementazione di Chrome con specifiche e altri browser.

Disattivazione del metodo importScripts() asincrono

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

I browser tentano di mitigare i possibili motivi legati alle prestazioni di "download ed esecuzione di codice" memorizzando nella cache automaticamente tutto ciò che è stato inserito tramite importScripts(), vale a dire che, dopo il download iniziale, l'overhead associato all'esecuzione del codice importato è molto ridotto.

Affinché questo comando funzioni, però, il browser deve sapere che non ci saranno "sorprese" codice importato al service worker dopo il deployment dell'installazione. In base alle specifiche del service worker, la chiamata a importScripts() dovrebbe funzionare solo durante l'esecuzione sincrona dell'istanza script del service worker o, se necessario, in modo asincrono all'interno del gestore install.

Prima di Chrome 71, la chiamata a importScripts() in modo asincrono all'esterno del gestore install comportava al lavoro. A partire da Chrome 71, le chiamate genera un'eccezione di runtime (a meno che lo stesso URL non sia stato precedentemente importato in un gestore install), che corrisponde al comportamento degli 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 service worker 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 di URL ripetuti passati a cache.addAll()

Se utilizzi l'API Cache Storage insieme a un service worker, c'è un'altra piccola modifica Chrome 71 affinché rispetti le specifiche pertinenti. Quando lo stesso URL viene passati più volte a una singola chiamata a cache.addAll(), il indica che la promessa restituita dalla chiamata deve essere rifiutata.

Prima di Chrome 71, questa impostazione non veniva rilevata e gli URL duplicati venivano di fatto ignorati.

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

Questo logging è un preludio a Chrome 72: invece di un semplice avviso registrato, gli URL duplicati comporta il rifiuto di cache.addAll(). Se chiami cache.addAll() nell'ambito di una catena di promesse passati a InstallEvent.waitUntil(), come è prassi comune, il rifiuto potrebbe causare la mancata installazione del Service worker.

Ecco come potresti riscontrare dei 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 passati a cache.addAll() e alla memorizzazione nella cache di ciò alla fine sono due risposte equivalenti con URL diversi, come '/' e '/index.html', non attivano un rifiuto.

Testare l'implementazione del service worker su larga scala

I Service worker sono ampiamente implementati in tutti i principali "evergreen" browser su a questo punto. Se testi regolarmente la tua app web progressiva su diversi browser o se molti utenti che non utilizzano Chrome, è probabile che tu abbia già rilevato l'incoerenza e ha aggiornato il codice. Se però non lo hai notato, del browser in uso in altri browser, volevamo evidenziare il cambiamento prima di cambiare il comportamento di Chrome.