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.
Disattivazione del metodo importScripts() asincrono
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 motivi di "download ed esecuzione di codice sincrono" memorizzando automaticamente nella cache tutto ciò che è stato importato tramite importScripts()
. Ciò significa che dopo il download iniziale, l'overhead associato all'esecuzione del codice importato è 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 a importScripts()
in modo asincrono all'esterno del gestore install
avrebbe funzionato. 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 service worker, c'è un'altra piccola modifica in
Chrome 71 per allinearti alle specifiche pertinenti. 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.
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.
Testare l'implementazione del 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, nel caso in cui non avessi notato questo comportamento in altri browser, volevamo evidenziare il cambiamento prima di cambiare il comportamento di Chrome.