Você já se perguntou como alguns sites parecem continuar funcionando mesmo quando você está offline? O segredo é simples: esses sites têm service workers.

Os service workers são a principal tecnologia por trás de muitos dos recursos nativos de aplicativos da Web modernos.

O que são trabalhadores de serviço?

Os trabalhadores de serviço são um tipo especializado de Trabalhadores da Web JavaScript. Um service worker é um arquivo JavaScript que funciona um pouco como um servidor proxy. Ele captura solicitações de rede de saída do seu aplicativo, permitindo que você crie respostas personalizadas. Você pode, por exemplo, servir arquivos em cache para o usuário quando ele estiver offline.

Os service workers também permitem que você adicione recursos como sincronização em segundo plano aos seus aplicativos da web.

Por que trabalhadores de serviços?

Os desenvolvedores da Web vêm tentando expandir os recursos de seus aplicativos há muito tempo. Antes que os service workers surgissem, você poderia usar várias soluções para tornar isso possível. Um particularmente notável foi o AppCache, que tornou os recursos de armazenamento em cache convenientes. Infelizmente, ele teve problemas que o tornaram uma solução impraticável para a maioria dos aplicativos.

O AppCache parecia ser uma boa ideia porque permitia especificar recursos para armazenar em cache com muita facilidade. No entanto, ele fez muitas suposições sobre o que você estava tentando fazer e depois quebrou horrivelmente quando seu aplicativo não seguiu exatamente essas suposições. Leia Jake Archibald's (infelizmente intitulado, mas bem escrito) Cache de aplicativo é um babaca para mais detalhes. (Fonte: MDN)

Service workers são a tentativa atual de reduzir as limitações dos aplicativos da Web, sem as desvantagens de tecnologias como o AppCache.

Casos de uso para service workers

Então, o que exatamente os service workers permitem que você faça? Os service workers permitem que você adicione recursos característicos de aplicativos nativos ao seu aplicativo da web. Eles também podem fornecer uma experiência normal em dispositivos que não oferecem suporte a service workers. Aplicativos como esse às vezes são chamados Aplicativos da Web progressivos (PWAs).

Aqui estão alguns dos recursos que os service workers possibilitam:

  • Permitir que o usuário continue usando o aplicativo (ou pelo menos partes dele) quando não estiver mais conectado à Internet. Os service workers conseguem isso servindo ativos em cache em resposta a solicitações.
  • Em navegadores baseados em Chromium, um service worker é um dos requisitos para que um aplicativo Web seja instalável.
  • Os service workers são necessários para que seu aplicativo da Web possa implementar notificações por push.

O ciclo de vida de um Service Worker

Os service workers podem controlar as solicitações de um site inteiro ou apenas de uma parte das páginas do site. Uma página da Web específica pode ter apenas um service worker ativo e todos os service workers têm um ciclo de vida baseado em eventos. O ciclo de vida de um service worker geralmente se parece com isso:

  1. Cadastro e download do trabalhador. A vida de um service worker começa quando um arquivo JavaScript o registra. Se o registro for bem-sucedido, o service worker baixa e começa a ser executado dentro de um thread especial.
  2. Quando uma página controlada pelo service worker é carregada, o service worker recebe um evento 'install'. Este é sempre o primeiro evento que um service worker recebe e você pode configurar um ouvinte para esse evento dentro do worker. O evento 'install' geralmente é usado para buscar e/ou armazenar em cache quaisquer recursos que o service worker precise.
  3. Depois que o service worker termina de instalar, ele recebe um evento 'activate'. Este evento permite que o trabalhador limpe recursos redundantes usados ​​por trabalhadores de serviço anteriores. Se você estiver atualizando um service worker, o evento activate só será acionado quando for seguro fazer isso. Isso ocorre quando não há páginas carregadas ainda usando a versão antiga do service worker.
  4. Depois disso, o service worker tem controle total de todas as páginas que foram carregadas após o registro bem-sucedido.
  5. A última fase do ciclo de vida é a redundância, que ocorre quando o service worker é removido ou substituído por uma versão mais recente.

Como usar Service Workers em JavaScript

A API do Service Worker (MDN) fornece a interface que permite criar e interagir com service workers em JavaScript.

Os service workers lidam principalmente com solicitações de rede e outros eventos assíncronos. Como resultado, a API do service worker faz uso intenso de Promessas e programação assíncrona.

Para criar um service worker, a primeira coisa que você precisa fazer é chamar o navigator.serviceWorker.register() método. Veja como isso pode parecer:

E se ('serviceWorker' no navegador) {
navigator.serviceWorker.register('/sw.js').then(função(cadastro){
console.log('O registro do service worker foi bem-sucedido:', cadastro);
}).catch((erro) => { console.log('Falha no registro do service worker:', erro); });
} senão {
console.log('Os trabalhadores de serviço não são suportados.');
}

O bloco if mais externo realiza a detecção de recursos. Ele garante que o código relacionado ao service worker seja executado apenas em navegadores que ofereçam suporte a service workers.

Em seguida, o código chama o registro método. Ele passa o caminho para o service worker (relativo à origem do site) para registrá-lo e baixá-lo. o registro O método também aceita um parâmetro opcional chamado scope, que pode ser usado para limitar as páginas controladas pelo trabalhador. Os service workers controlam todas as páginas de um aplicativo por padrão. o registro O método retorna uma promessa que indica se o registro foi bem-sucedido.

Se a promessa for resolvida, o service worker foi registrado com sucesso. O código então imprime um objeto que representa o service worker registrado no console.

Se o processo de registro falhar, o código detecta o erro e o registra no console.

Em seguida, aqui está um exemplo simplificado de como o próprio service worker pode ser:

self.addEventListener('instalar', (evento) => {
event.waitAté(novoPromessa((resolver, rejeitar) => {
console.log("fazendo coisas de configuração")
resolver()
}))
console.log("Service worker terminou de instalar")
})

self.addEventListener('ativar', (evento) => {
event.waitAté(novoPromessa((resolver, rejeitar) => {
console.log("fazendo coisas de limpeza!")
resolver()
}))
console.log('ativação feita!')
})

self.addEventListener('buscar', (evento) => {
console.log("Solicitação interceptada", evento)
});

Este trabalhador de serviço de demonstração tem três ouvintes de eventos, registrados em relação a si mesmo. Ele tem um para o evento 'install', o evento 'activate' e o evento 'fetch'.

Dentro dos dois primeiros ouvintes, o código usa o espere até método. Este método aceita uma Promise. Seu trabalho é garantir que o service worker espere a Promise ser resolvida ou rejeitada antes de passar para o próximo evento.

O listener de busca é acionado sempre que uma solicitação é feita para um recurso controlado pelo service worker.

Os recursos controlados por um service worker incluem todas as páginas que ele controla, bem como quaisquer ativos referenciados nessas páginas.

Aprimore seus aplicativos da Web com service workers

Service workers são um tipo especial de web workers que atendem a um propósito único. Eles ficam na frente de solicitações de rede para habilitar recursos como acesso offline a aplicativos. O uso de service workers em um aplicativo da Web pode melhorar muito a experiência do usuário. Você pode criar service workers e interagir com eles usando a API do service worker.