We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

Essencialmente, um service worker se comporta como um servidor proxy situado entre uma aplicação web, o navegador e a rede (quando esta estiver disponível). Eles servem, dentre outras coisas, para possibilitar a criação de experiências offline eficientes, interceptar requisições de rede – agindo adequadamente de acordo com o status atual da conexão – e atualizar os assets que residem no servidor. Service workers também permitem o acesso às APIs de push notification e background sync.

Service worker - Conceitos e uso

Um service worker é um tipo especial de worker baseado em eventos, o qual é registrado para um determinado path e origem. Na prática, ele é um arquivo JavaScript que pode controlar as páginas do site ao qual ele está associado, interceptando e modificando requisições e a navegação em si. Ele também faz cache dos recursos trafegados de maneira bastante granular, visando oferecer controle total sobre como a sua aplicação se comporta em determinadas situações (o exemplo mais óbvio, naturalmente, é quando não há conexão de rede disponível).

Assim como outros tipos de worker, um service worker é executado em um contexto isolado. Dessa forma, não tem acesso ao DOM e roda em uma thread completamente separada, sendo incapaz de realizar operações blocantes. Service workers foram projetados para ser totalmente assíncronos; como consequência disso, não permitem o acesso a APIs como XHR síncrono e localStorage.  

Por questões de segurança, service workers funcionam apenas em sites servidos via HTTPS. A possibilidade de modificar requisições em um domínio desprotegido contra ataques do tipo man-in-the-middle seria desastrosa. No Firefox, é vetado o acesso à API de service workers para sites abertos no Modo de navegação privativa.

Nota: Os service workers superaram tentativas anteriores de resolver problemas semelhantes, como o AppCache. Há uma explicação simples para eles terem sido bem-sucedidos: Service workers não tentam adivinhar o que você está tentando fazer e, muito menos, deixam de funcionar caso não tenham adivinhado corretamente. Pelo contrário, você tem o controle milimétrico de tudo.    

Nota: Service workers fazem uso intenso de promessas, uma vez que eles têm de esperar por respostas assíncronas para, após retornadas, poderem executar a ação apropriada (de sucesso ou erro). A arquitetura de promessas é ideal para esse tipo de cenário.

 

Registrando

O registro inicial de um service worker é feito através do método ServiceWorkerContainer.register(). Se bem-sucedido, seu service worker será descarregado no cliente e então ocorrerá a tentativa de instalação/ativação para as URLs acessadas pelo usuário sob a origem registrada ou, caso deseje, apenas dentro de um subconjunto limitado por você.

Download, instalação e ativação

Nesse estágio, seu service worker seguirá o seguinte ciclo de vida:

  1. Download
  2. Instalação
  3. Ativação

Quando o usuário acessa pela primeira vez um site ou página controlado por um service worker, ele é descarregado imediatamente.

Após isso, serão feitos novos downloads em intervalos de aproximadamente 24 horas. O download pode ocorrer mais frequentemente, mas ele precisa ser feito a cada 24 horas para prevenir que scripts ruins sejam um problema por períodos muito extensos. 

A tentativa de instalação é feita sempre que o arquivo descarregado é identificado como novo – seja por diferir dos service workers pré-existentes (é feita uma comparação binária nessa etapa) ou por ser o primeiro descoberto para a página ou site em questão.

Na primeira vez que um service worker é disponibilizado, é feita a tentativa de instalação. Se bem-sucedida, ele é ativado.

Se, por outro lado, já existe um service worker pré-instalado para uma página ou site e for disponibilizada uma nova versão, ela será descarregada, mas não imediatamente ativada. Isso é chamado de worker em espera. Só será efetuada a ativação da versão atualizada quando não houver mais páginas utilizando a anterior. Após isso, ele passa a ser o worker ativo. Caso necessário, é possível pular a etapa de espera com o método ServiceWorkerGlobalScope.skipWaiting(). Em seguida, o novo worker ativo pode reivindicar as páginas existentes usando Clients.claim()

Você pode adicionar um listener para o evento InstallEvent. Uma ação padrão, quando esse evento é disparado, é preparar o seu service worker para ser utilizado (por exemplo: criado um cache usando a API de storage nativa e armazenando nela os assets que você quer que permaneçam disponíveis caso a aplicação fique offline).

Há também o evento activate. O momento em que ele é disparado é geralmente o ideal para limpar caches antigos e outras coisas associadas com a versão anterior do seu service worker.

Seu service worker pode responder a requisições usando o FetchEvent. Você pode manipular a resposta a essas requisições da maneira que quiser, através do método FetchEvent.respondWith.

Nota: Como oninstall e onactivate podem demorar a serem concluídos, a especificação de service workers disponibiliza um método waitUntil. Ele recebe como parâmetro uma promessa, notificando o navegador que há trabalho em andamento até que aquela promessa seja resolvida. O navegador, portanto, não deverá encerrar o service worker durante esse período de espera. 

Para um tutorial completo, mostrando como construir seu primeiro exemplo do zero, leia Usando Service Workers.

Outras ideias de usos possíveis

  • Sincronização de dados em background
  • Responder a requisições de recursos a partir de outras origens
  • Receber de forma centralizada atualizações para dados de cálculo mais custoso, como geolocalização ou giroscópio, de forma a permitir que múltiplas páginas façam uso de um único conjunto de dados.
  • No lado do cliente, fazer compilação e gerenciamento de dependências para CoffeeScript, LESS, módulos CommonJS/AMD, entre outros.  
  • Hooks para serviços em background.
  • Templates customizados com base em certos padrões de URL.
  • Melhorias de performance como, por exemplo, fazer o pré-carregamento de recursos que o usuário provavelmente irá precisar a curto prazo, como as próximas fotos de um álbum.

No futuro, service workers serão capazes de fazer várias outras coisas úteis para a plataforma web, deixando-a mais próxima de apps nativos em.

É interessante mencionar que outras especificações podem e irão passar a usar o contexto de service workers, por exemplo:

  • Sincronização em background: Iniciar um service worker mesmo quando não há usuários no site, de forma que o cache possa ser atualizado;
  • Reagir a mensagens push: Iniciar um service worker para enviar uma mensagem aos usuários dizendo que há conteúdo novo disponível;
  • Reagir a uma data/hora específica;
  • Entrar em uma geo-fence.

Interfaces

Cache
Representa o armazenamento para os pares de objeto RequestResponse, os quais são cacheados como parte do ciclo de vida do ServiceWorker.
CacheStorage
Representa o armazenamento para objetos Cache. Ele disponibiliza um diretório-mestre com todos os caches nomeados que um ServiceWorker pode acessar, mantendo o mapeamento de nomes para os objetos Cache correspondentes.
Client
Representa o escopo do cliente de um service worker. Um cliente pode ser um documento no contexto de um navegador ou um SharedWorker, o qual é controlado por um worker ativo.
Clients
Representa o container para uma lista de objetos Client. É a principal forma de acessar os clientes na origem atual para o service worker ativo.
ExtendableEvent
Estende a vida dos eventos install e activate disparados no ServiceWorkerGlobalScope, como parte do ciclo de vida do service worker. Isso garante que qualquer evento funcional (como o FetchEvent) não seja despachado para o ServiceWorker até que ele conclua as ações em andamento, como por exemplo: atualizar esquemas de banco de dados, apagar caches defasados, etc.
ExtendableMessageEvent
O objeto de evento do message, o qual é disparado em um service worker (quando uma mensagem de canal é recebida no ServiceWorkerGlobalScope a partir de outro contexto) — estende o tempo de vida desses eventos.
FetchEvent
O parâmetro recebido no handler  ServiceWorkerGlobalScope.onfetch. O FetchEvent representa uma ação de descarregamento que é despachada no ServiceWorkerGlobalScope de um  ServiceWorker. Ele contém informações sobre a requisição e a resposta resultante, além de disponibilizar o método FetchEvent.respondWith(), o qual nos permite devolver uma resposta customizada para a página que está sendo controlada.
InstallEvent
O parâmetro recebido no handler  oninstall. A interface InstallEvent representa uma ação de instalação que é despachada no ServiceWorkerGlobalScope de um  ServiceWorker. Como deriva do ExtendableEvent, ele assegura que eventos funcionais, como o FetchEvent, não sejam despachados durante a instalação. 
NavigationPreloadManager
Disponibiliza métodos para gerenciar o pré-carregamento de recursos com um service worker. 
Navigator.serviceWorker
Retornar um objeto ServiceWorkerContainer, o qual permite accesso ao registro, remoção, atualização e comunicação com os objetos ServiceWorker para o documento associado.
NotificationEvent
O parâmetro recebido no handler  onnotificationclick. A interface NotificationEvent representa um evento de click em uma notificação que é despachado no ServiceWorkerGlobalScope de um ServiceWorker.
ServiceWorker
Representa um service worker. Diferentes contextos de navegação (ex: páginas, workers, etc.) podem ser associados com o mesmo objeto ServiceWorker.
ServiceWorkerContainer
Disponibiliza um objeto representando o service worker como uma unidade global no ecossistema de rede, incluindo métodos para registrar, desregistrar e atualizar service workers, além de poder acessar o status de cada worker e seus registros.
ServiceWorkerGlobalScope
Representa o contexto de execução global de um service worker.
ServiceWorkerMessageEvent
Representa uma mensagem enviada a um ServiceWorkerGlobalScope. Vale ressaltar que essa interface está defasada em navegadores modernos. As mensagens de service worker agora usam a interface MessageEvent para manter consistência com outras funcionalidades de messageria da web.
ServiceWorkerRegistration
Representa o registro de um service worker.
ServiceWorkerState
Associado com o estado do ServiceWorker.
SyncEvent

A interface SyncEvent representa uma ação de sincronização que é despachada no ServiceWorkerGlobalScope de um ServiceWorker. 

SyncManager
Disponibiliza uma interface para registrar e listar registros de sincronização.
WindowClient
Representa o escopo de um cliente de service worker que é um documento em um contexto de navegador, o qual é controlado por um worker ativo. Esse é um tipo especial de objeto Client, como alguns métodos e propriedades adicionais disponíveis.

Especificações

Especificação Status Comentário
Service Workers Rascunho atual Initial definition.

Compatibilidade de Navegador

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Recurso Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Suporte básico 40 Não suportado[1] 44.0 (44.0)[2] Não suportado 24 Não suportado[3]
Eventos install/activate 40 Não suportado[1] 44.0 (44.0)[2] Não suportado (Yes) Não suportado
Evento fetch/request/
respondWith()
40 Não suportado[1] 44.0 (44.0)[2] Não suportado Não suportado Não suportado
caches/cache

42

Não suportado[1] 39.0 (39.0)[2] Não suportado Não suportado Não suportado
ServiceWorkerMessageEvent defasado em favor MessageEvent

57

Não suportado 55.0 (55.0)[2] Não suportado Não suportado Não suportado
NavigationPreloadManager 59 Não suportado   Não suportado 46 Não suportado
Recursos Android Webview Chrome for Android Edge Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
Suporte básico Não suportado 40 Não suportado[1] 44.0 (44.0) Não suportado (Yes) Não suportado[3]
Eventos install/activate Não suportado 40 Não suportado[1] 44.0 (44.0) Não suportado (Yes) Não suportado
Evento fetch/request/
respondWith()
Não suportado 40 Não suportado[1] 44.0 (44.0) Não suportado Não suportado Não suportado
caches/cache Não suportado 40 Não suportado[1] 39.0 (39.0) Não suportado Não suportado Não suportado
ServiceWorkerMessageEvent defasado em favor de MessageEvent Não suportado

57

Não suportado 55.0 (55.0) Não suportado Não suportado Não suportado
NavigationPreloadManager Não suportado 59 Não suportado Não suportado Não suportado 46 Não suportado

[1] Esse recurso ainda não é suportado, apesar de já estar em desenvolvimento.

[2] Service workers (e Push) foram desabilitados no Firefox, nas versões 45 & 52 Extended Support Releases (ESR.)

[3] Esse recurso ainda não é suportado, apesar de já estar em desenvolvimento.

Veja também

Etiquetas do documento e colaboradores

Colaboradores desta página: alcidesqueiroz, dicarlosdesign
Última atualização por: alcidesqueiroz,