Como remover service workers com bugs

Às vezes, um service worker com bugs é implantado, e há problemas. Por exemplo, um service worker pode ser analisado no momento do registro e concluído com sucesso. No entanto, o código com bugs em um evento fetch pode fazer com que ele não responda às solicitações, resultando em uma página em branco. Outra possibilidade é que a marcação de página seja armazenada em cache de forma agressiva, e um service worker só retorna respostas de marcação desatualizadas de uma instância de Cache para visitas subsequentes.

Há muitas maneiras de um service worker dar errado, e isso é um problema assustador em um site de produção. Mesmo assim, nem tudo está perdido. Há maneiras de corrigir a situação e voltar aos trilhos.

Implantar um service worker autônomo

Geralmente, para lidar com um service worker com bugs, basta implantar um service worker ambiente autônomo, que precisa ser instalado e ativado imediatamente sem um manipulador de eventos 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);
    });
  });
});

Esse service worker será instalado e ativado imediatamente chamando self.skipWaiting() no evento install. Opcionalmente, outro código pode ser implantado no evento activate para forçar a atualização de qualquer outra guia aberta com um WindowClient que o service worker esteja controlando.

É muito importante que um service worker autônomo não contenha nenhum manipulador de eventos fetch. Quando um service worker não processa solicitações, elas são transmitidas para o navegador como se nenhum service worker estivesse presente. Depois que um service worker autônomo é implantado, o service worker com bugs pode ser corrigido e implantado como uma atualização mais tarde.

Em parte, essa abordagem funciona porque os navegadores têm proteções fortes contra colocar service workers no cache HTTP e porque eles executam verificações byte a byte do conteúdo de um service worker para atualizações. Esses padrões permitem implantar uma substituição de ambiente autônomo para um service worker com bugs para corrigir o problema rapidamente.

Outras medidas a serem tomadas

A implantação de um service worker autônomo é suficiente para neutralizar um que apresente bugs, mas outras medidas podem ser tomadas, se necessário.

E se você não souber o URL do service worker antigo?

Às vezes, o URL do service worker instalado anteriormente é desconhecido. Isso pode ter acontecido porque ele tem controle de versão (por exemplo, contém um hash no nome do arquivo). Nesse caso, pode ser um desafio implantar um service worker autônomo que corresponda ao URL de cada service worker antigo que possa estar registrado. Isso vai contra as práticas recomendadas, porque os desenvolvedores provavelmente não se lembrarão de cada hash para cada versão do service worker implantada.

Felizmente, um cabeçalho de solicitação HTTP útil é enviado com uma solicitação para um script de service worker: Service-Worker. No servidor da Web, verifique esse cabeçalho e intercepte a solicitação para disponibilizar um service worker autônomo. Esse recurso depende do servidor da Web e da pilha de back-end usados, portanto consulte a documentação da linguagem relevante sobre como fazer isso.

Quanto às futuras implantações de service workers, use nomes de recursos sem versão (por exemplo, sw.js). Isso tornará as coisas muito menos complicadas no futuro.

Definir um cabeçalho Clear-Site-Data

Alguns navegadores cancelarão o registro de todos os service workers de uma origem se um cabeçalho de resposta Clear-Site-Data com um valor 'storage' estiver definido. No entanto, há algumas coisas que você precisa saber com essa abordagem:

Como o suporte a esse cabeçalho não é total, ele não pode ser confiável para corrigir o problema. Portanto, é melhor ver Clear-Site-Data como uma medida, além de implantar um service worker autônomo.

O dano não é permanente

Pode ser assustador quando a experiência do usuário é interrompida por um service worker com bugs, especialmente em sites grandes e conhecidos, mas o dano é temporário e reversível.

Se for necessário implantar um service worker autônomo para corrigir a situação, dedique um tempo após o fato para descobrir exatamente o que deu errado. No futuro, garanta que um service worker processe apenas as solicitações esperadas. Realize testes com frequência no preparo e implante atualizações apenas quando tiver confiança.