Os desenvolvedores que usam service workers e a API Cache Storage precisam ficar de olho em duas pequenas mudanças lançadas no Chrome 71. Ambas as mudanças alinham a implementação do Chrome com as especificações e outros navegadores.
Como desativar o importScripts() assíncrono
importScripts()
informa ao script principal do service worker para pausar a execução atual, fazer o download de outro código de
um determinado URL e executá-lo até a conclusão no escopo global atual. Depois disso,
o script principal do worker de serviço retoma a execução. O importScripts()
é útil quando
você quer dividir o script principal do service worker em partes menores por motivos organizacionais ou
extrair o código de terceiros para adicionar funcionalidade ao service worker.
Os navegadores tentam mitigar os possíveis problemas de desempenho de "fazer o download e executar algum código
síncrono" armazenando em cache automaticamente tudo o que é puxado por importScripts()
. Isso significa que, após o
download inicial, há pouca sobrecarga envolvida na execução do código importado.
Para que isso funcione, o navegador precisa saber que não haverá nenhum código "surpresa" importado
para o service worker após a instalação inicial.
De acordo com a especificação do service worker,
a chamada de importScripts()
só funciona durante a execução síncrona do script de service worker
de nível superior ou, se necessário, de forma assíncrona no gerenciador install
.
Antes do Chrome 71, chamar importScripts()
de forma assíncrona fora do gerenciador install
funcionava. A partir do Chrome 71, essas chamadas
geram uma exceção de execução, a menos que o mesmo URL tenha sido importado anteriormente em um gerenciador install
,
correspondendo ao comportamento em outros navegadores.
Em vez de um código como este:
// This only works in Chrome 70 and below.
self.addEventListener('fetch', event => {
importScripts('my-fetch-logic.js');
event.respondWith(self.customFetchLogic(event));
});
O código do worker de serviço vai ficar assim:
// 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));
});
URLs repetidos descontinuados transmitidos para cache.addAll()
Se você estiver usando a API Cache Storage com um worker de serviço, haverá outra pequena mudança no
Chrome 71 para se alinhar à especificação relevante. Quando o mesmo URL é
transmitido várias vezes para uma única chamada para
cache.addAll()
, a
especificação diz que a promessa retornada pela chamada precisa ser rejeitada.
Antes do Chrome 71, isso não era detectado, e os URLs duplicados eram ignorados.
Esse registro é um prelúdio para o Chrome 72, em que, em vez de apenas um aviso registrado, URLs duplicados
levarão à rejeição de cache.addAll()
. Se você estiver chamando cache.addAll()
como parte de uma cadeia de promessas
transmitida para
InstallEvent.waitUntil()
,
como é prática comum, essa rejeição pode fazer com que o service worker não seja instalado.
Confira como você pode ter problemas:
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))
);
});
Essa restrição se aplica apenas aos URLs reais transmitidos para cache.addAll()
, e o armazenamento em cache do que
acaba sendo duas respostas equivalentes com URLs diferentes, como '/'
e '/index.html'
, não
aciona uma rejeição.
Testar a implementação do worker do serviço de forma ampla
Os service workers são amplamente implementados em todos os principais navegadores"evergreen". Se você testa regularmente seu app da Web progressivo em vários navegadores ou se tem um número significativo de usuários que não usam o Chrome, é provável que já tenha detectado a inconsistência e atualizado o código. No entanto, caso você não tenha notado esse comportamento em outros navegadores, gostaríamos de destacar a mudança antes de alterar o comportamento do Chrome.