API do Service Worker
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:
- Download
- Instalação
- 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
eonactivate
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
Request
eResponse
, os quais são cacheados como parte do ciclo de vida doServiceWorker
. CacheStorage
-
Representa o armazenamento para objetos
Cache
. Ele disponibiliza um diretório-mestre com todos os caches nomeados que umServiceWorker
pode acessar, mantendo o mapeamento de nomes para os objetosCache
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
eactivate
disparados noServiceWorkerGlobalScope
, como parte do ciclo de vida do service worker. Isso garante que qualquer evento funcional (como oFetchEvent
) não seja despachado para oServiceWorker
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
unsupported templ: event, o qual é disparado em um service worker (quando uma mensagem de canal é recebida noServiceWorkerGlobalScope
a partir de outro contexto) — estende o tempo de vida desses eventos. FetchEvent
-
O parâmetro recebido no handler
ServiceWorkerGlobalScope.onfetch
. OFetchEvent
representa uma ação de descarregamento que é despachada noServiceWorkerGlobalScope
de umServiceWorker
. Ele contém informações sobre a requisição e a resposta resultante, além de disponibilizar o métodoFetchEvent.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 interfaceInstallEvent
representa uma ação de instalação que é despachada noServiceWorkerGlobalScope
de umServiceWorker
. Como deriva doExtendableEvent
, ele assegura que eventos funcionais, como oFetchEvent
, não sejam despachados durante a instalação. -
Disponibiliza métodos para gerenciar o pré-carregamento de recursos com um service worker.
-
Retornar um objeto
ServiceWorkerContainer
, o qual permite accesso ao registro, remoção, atualização e comunicação com os objetosServiceWorker
para o documento associado. NotificationEvent
-
O parâmetro recebido no handler
onnotificationclick
. A interfaceNotificationEvent
representa um evento de click em uma notificação que é despachado noServiceWorkerGlobalScope
de umServiceWorker
. 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
Deprecated-
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 interfaceMessageEvent
para manter consistência com outras funcionalidades de messageria da web. ServiceWorkerRegistration
-
Representa o registro de um service worker.
ServiceWorkerState
Experimental-
Associado com o estado do
ServiceWorker
. SyncEvent
Non-standard-
A interface SyncEvent representa uma ação de sincronização que é despachada no
ServiceWorkerGlobalScope
de um ServiceWorker. SyncManager
Non-standard-
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
Specification |
---|
Service Workers |