Service Workers

Os usuários esperam que os apps sejam iniciados de maneira confiável em conexões de rede lentas ou instáveis ou até mesmo off-line. Ele espera que o conteúdo com que interagiu mais recentemente, como faixas de mídia ou ingressos e itinerários, esteja disponível e usável. Quando uma solicitação não é possível, eles esperam que o app informe, em vez de falhar ou falhar silenciosamente. E eles querem que tudo isso aconteça rapidamente. Como você pode ver em Milissegundos geram milhões, mesmo uma melhoria de 0,1 segundo nos tempos de carregamento pode melhorar a conversão em até 10%. Service workers são a ferramenta que permite que seu Progressive Web App (PWA) atenda às expectativas dos seus usuários.

Um service worker como proxy de middleware, executado no lado do dispositivo, entre o PWA e os servidores, o que inclui seus próprios servidores e servidores de vários domínios.
Um service worker atua como um middleware entre o PWA e os servidores com que ele interage.

Quando um app solicita um recurso coberto pelo escopo do service worker, o service worker intercepta a solicitação e atua como um proxy de rede, mesmo que o usuário esteja off-line. Assim, ele pode decidir se precisa disponibilizar o recurso do cache usando a API Cache Storage, exibi-lo pela rede como se não houvesse service worker ativo ou criá-lo com base em um algoritmo local. Isso permite que você ofereça uma experiência de alta qualidade como a de um app de plataforma, mesmo quando seu app estiver off-line.

Registrar um service worker

Antes que um service worker assuma o controle da sua página, ela precisa ser registrada para seu PWA. Isso significa que, na primeira vez que um usuário abrir o PWA, todas as solicitações de rede vão diretamente para seu servidor porque o service worker ainda não tem controle sobre as páginas.

Depois de verificar se o navegador é compatível com a API Service Worker, o PWA poderá registrar um service worker. Depois de carregar, o service worker se configura entre o PWA e a rede, interceptando solicitações e exibindo as respostas correspondentes.

if ('serviceWorker' in navigator) {
   navigator.serviceWorker.register("/serviceworker.js");
}
Tente registrar um service worker e ver o que acontece nas ferramentas para desenvolvedores do seu navegador.

Verificar se um service worker está registrado

Para verificar se um service worker está registrado, use as ferramentas para desenvolvedores no seu navegador favorito.

Em navegadores baseados no Firefox e no Chromium (Microsoft Edge, Google Chrome ou Samsung Internet):

  1. Abra as ferramentas de desenvolvedor e clique na guia Aplicativo.
  2. No painel esquerdo, selecione Service Workers.
  3. Verifique se o URL do script do service worker aparece com o status "Ativado". Para mais informações, consulte Ciclo de vida. No Firefox, o status pode ser "Em execução" ou "Interrompido".

No Safari:

  1. Clique em Develop > Service Workers.
  2. Procure nesse menu uma entrada com a origem atual. Um clique nessa entrada abre um inspetor sobre o contexto do service worker.
Ferramentas para desenvolvedores de service worker no Chrome, Firefox e Safari.
Ferramentas para desenvolvedores de service worker no Chrome, Firefox e Safari.

Escopo

A pasta em que o service worker está localizado determina o escopo. Um service worker que reside em example.com/my-pwa/sw.js pode controlar qualquer navegação no caminho my-pwa ou abaixo dele, como example.com/my-pwa/demos/. Os service workers podem controlar apenas itens (páginas, workers, coletivamente "clientes") em seu escopo. Este escopo se aplica às guias do navegador e às janelas do PWA.

Somente um service worker é permitido por escopo. Quando um service worker está ativo e em execução, normalmente apenas uma instância fica disponível, independente de quantos clientes (janelas do PWA ou guias do navegador) estão na memória.

O Safari tem gerenciamento de escopo mais complexo, conhecido como partições, afetando o funcionamento dos escopos com iframes de vários domínios. Para saber mais sobre a implementação do WebKit, consulte a postagem do blog (link em inglês).

Ciclo de vida

Os service workers têm um ciclo de vida que dita como eles são instalados, separadamente da instalação do PWA.

O ciclo de vida do service worker começa com o registro dele. Em seguida, o navegador tenta fazer o download e analisar o arquivo do service worker. Se a análise for bem-sucedida, o evento install do service worker será disparado. O evento install é acionado apenas uma vez.

A instalação do service worker acontece silenciosamente, sem precisar da permissão do usuário, mesmo que ele não instale o PWA. A API Service Worker está disponível mesmo em plataformas que não oferecem suporte à instalação de PWA, como Safari e Firefox em dispositivos desktop.

Após a instalação, o service worker precisa ser ativado antes de controlar os clientes, incluindo o PWA. Quando o service worker estiver pronto para controlar os clientes, o evento activate será disparado. No entanto, por padrão, um service worker ativado não pode gerenciar a página que o registrou até a próxima vez que você acessar essa página recarregando ou reabrindo o PWA.

É possível detectar eventos no escopo global do service worker usando o objeto self:

serviceworker.js

// This code executes in its own worker or thread
self.addEventListener("install", event => {
   console.log("Service worker installed");
});
self.addEventListener("activate", event => {
   console.log("Service worker activated");
});

Atualizar um service worker

Os service workers são atualizados quando o navegador detecta que o service worker que controla o cliente e a nova versão do arquivo do service worker do servidor são diferentes em bytes.

Após uma instalação bem-sucedida, o novo service worker aguarda a ativação até que o antigo não controle mais nenhum cliente. Esse estado é chamado de "espera" e é como o navegador garante que apenas uma versão do service worker esteja em execução por vez.

Atualizar uma página ou reabrir o PWA não fará com que o novo service worker assuma o controle. O usuário precisa fechar ou sair de todas as guias e janelas usando o service worker atual e, em seguida, voltar para dar controle ao novo service worker. Para mais informações, consulte O ciclo de vida do service worker.

Vida útil do service worker

Um service worker instalado e registrado pode gerenciar todas as solicitações de rede dentro do escopo. Ele é executado na própria linha de execução, com ativação e encerramento controlados pelo navegador, o que permite que ele funcione mesmo antes de o PWA ser aberto ou depois de fechado. Service workers são executados na própria linha de execução, mas o estado na memória pode não persistir entre execuções de um service worker. Portanto, verifique se tudo que você quer reutilizar para cada execução está disponível no IndexedDB ou em algum outro armazenamento permanente.

Se ainda não estiver em execução, um service worker será iniciado sempre que uma solicitação de rede for enviada no escopo ou quando ele receber um evento de acionamento, como uma sincronização periódica em segundo plano ou uma mensagem de push.

Os service workers serão encerrados se ficarem inativos por alguns segundos ou se estiverem ocupados por muito tempo. O tempo para isso varia de acordo com o navegador. Se um service worker tiver sido encerrado e ocorrer um evento que o inicie, ele será reiniciado.

Recursos

Um service worker registrado e ativo usa uma linha de execução com um ciclo de vida de execução completamente diferente da linha de execução principal do PWA. No entanto, por padrão, o arquivo do service worker em si não tem comportamento. Ele não armazena em cache nem exibe recursos. Isso é o que seu código precisa fazer. Você saberá como fazer isso nos próximos capítulos.

Os recursos do service worker não são apenas para proxy ou disponibilização de solicitações HTTP. Outros recursos também estão disponíveis para outras finalidades, como execução de código em segundo plano, notificações push da Web e pagamentos de processos. Discutiremos essas adições em Recursos.

Recursos