Como trabalhar com service workers

Este codelab mostra como registrar um service worker no seu aplicativo da Web e usar o Chrome DevTools para observar o comportamento dele. Também aborda algumas técnicas de depuração que podem ser úteis ao lidar com service workers.

Conhecer o projeto de exemplo

Os arquivos no projeto de exemplo mais relevantes para este codelab são:

  • register-sw.js começa vazio, mas contém o código usado para registrar o service worker. Ele já está sendo carregado por uma tag <script> dentro do index.html do projeto.
  • service-worker.js também está vazio. É o arquivo que vai conter o service worker para este projeto.

Adicionar o código de registro do service worker

Um service worker (mesmo vazio, como o arquivo service-worker.js atual) não será usado, a menos que seja registrado primeiro. Você pode fazer isso por meio de uma chamada para:

navigator.serviceWorker.register(
  '/service-worker.js'
)

no arquivo register-sw.js.

No entanto, antes de adicionar esse código, há alguns pontos a serem considerados.

Primeiro, nem todo navegador é compatível com service workers. Isso é válido principalmente para versões mais antigas de navegadores que não são atualizadas automaticamente. Portanto, é uma prática recomendada chamar navigator.serviceWorker.register() condicionalmente, depois de verificar se navigator.serviceWorker tem suporte.

Em segundo lugar, quando você registra um service worker, o navegador executa o código no arquivo service-worker.js e pode começar a fazer o download de URLs para preencher os caches, dependendo do código nos manipuladores de eventos install e activate do service worker.

A execução de mais códigos e o download de recursos pode consumir recursos valiosos que seu navegador poderia usar para exibir a página da Web atual. Para evitar essa interferência, é recomendável atrasar o registro de um service worker até que o navegador termine de renderizar a página atual. Uma maneira conveniente de fazer uma aproximação é esperar até que o evento window.load seja disparado.

Juntando esses dois pontos, adicione este código de registro de service worker de uso geral ao arquivo register-sw.js:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js');
  });
}

Adicione um código de geração de registros do service worker

O arquivo service-worker.js é onde toda a lógica da implementação do service worker normalmente normalmente teria. Use uma combinação dos eventos de ciclo de vida do service worker, a API Cache Storage e conhecimento sobre o tráfego de rede do seu app da Web para criar um service worker perfeitamente elaborado, pronto para lidar com todas as solicitações do seu app da Web.

Mas... isso é tudo para aprender mais tarde. Nesta fase, o foco é observar vários eventos de service worker e se familiarizar com o uso do DevTools do Chrome para depurar o estado do service worker.

Para isso, adicione o seguinte código ao service-worker.js, que registrará mensagens no console do DevTools em resposta a vários eventos, mas não fará muito mais:

self.addEventListener('install', (event) => {
  console.log('Inside the install handler:', event);
});

self.addEventListener('activate', (event) => {
  console.log('Inside the activate handler:', event);
});

self.addEventListener(fetch, (event) => {
  console.log('Inside the fetch handler:', event);
});

Conheça o painel Service Workers no DevTools

Agora que você adicionou o código aos arquivos register-sw.js e service-worker.js, é hora de acessar a versão ativa do projeto de exemplo e observar o service worker em ação.

  • Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia modo tela cheia.
  • Pressione "Control + Shift + J" (ou "Command + Option + J" no Mac) para abrir o DevTools.
  • Clique na guia Console.

Você verá algo parecido com as mensagens de registro a seguir, mostrando que o service worker foi instalado e ativado:

Mostra que o service worker está instalado e ativado.

Em seguida, acesse a guia Aplicativos e selecione o painel Service Workers. Será exibido um resultado parecido com este:

Mostra os detalhes do service worker no painel correspondente.

Isso informa que há um service worker com um URL de origem de service-worker.js, para o app da Web solar-donkey.glitch.me, que está ativado e em execução no momento. Ele também informa que há um cliente (guia aberta) que está sendo controlado pelo service worker.

Use os links neste painel, como Unregister ou stop, para fazer mudanças no service worker registrado no momento para fins de depuração.

Acionar o fluxo de atualização do service worker

Um dos principais conceitos que você precisa entender ao desenvolver com service workers é a ideia de um fluxo de atualização.

Depois que os usuários acessarem um app da Web que registra um service worker, eles vão receber o código da cópia atual do service-worker.js instalada no navegador local. O que acontece quando você faz atualizações na versão do service-worker.js armazenada no servidor da Web?

Quando um visitante recorrente retorna a um URL que está dentro do escopo de um service worker, o navegador solicita automaticamente o service-worker.js mais recente e verifica se há alterações. Se algo no script do service worker for diferente, o novo service worker terá a chance de instalar, ativar e, por fim, assumir o controle.

Para simular esse fluxo de atualização, volte ao editor de código do seu projeto e faça qualquer alteração no código. Uma mudança rápida seria substituir

self.addEventListener('install', (event) => {
  console.log('Inside the install handler:', event);
});

para os recursos de

self.addEventListener('install', (event) => {
  console.log('Inside the UPDATED install handler:', event);
});

Depois de fazer essa mudança, retorne à versão ativa do app de exemplo e recarregue a página com a guia "Application" do DevTools ainda aberta. Você verá algo parecido com isto:

Mostra duas versões do service worker instaladas.

Isso mostra que há duas versões do service worker instaladas neste ponto. A versão anterior, que já estava ativada, está em execução e no controle da página atual. A versão atualizada do service worker está listada abaixo. Ela está no estado waiting e vai continuar aguardando até que todas as guias abertas controladas pelo service worker antigo sejam fechadas.

Esse comportamento padrão garante que, se o novo service worker tiver uma diferença fundamental de comportamento em relação ao antigo, como um gerenciador fetch que responde com recursos incompatíveis com versões mais antigas do seu app da Web, ele não entrará em vigor até que um usuário tenha encerrado todas as instâncias anteriores do app.

Resumindo

Agora você já sabe como registrar um service worker e observar o comportamento dele usando o DevTools do Chrome.

Agora você está em uma boa posição para começar a implementar estratégias de armazenamento em cache e aproveitar todos os recursos que ajudarão seu app da Web a carregar de maneira confiável e rápida.