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 (en-US) 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()` (en-US). Em seguida, o novo worker ativo pode reivindicar as páginas existentes usando `Clients.claim()` (en-US).

Você pode adicionar um *listener* para o evento `InstallEvent` (en-US). 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` (en-US). Você pode manipular a resposta a essas requisições da maneira que quiser, através do método `FetchEvent.respondWith` (en-US).

> 
> \*\*Nota:\*\*Como `oninstall` e `onactivate` podem demorar a serem concluídos, a especificação de *service workers* disponibiliza um método waitUntil (en-US). 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 (en-US).

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` e `Response`, os quais são cacheados como parte do ciclo de vida do `ServiceWorker` (en-US).

`CacheStorage` (en-US)

Representa o armazenamento para objetos `Cache`. Ele disponibiliza um diretório-mestre com todos os caches nomeados que um `ServiceWorker` (en-US) pode acessar, mantendo o mapeamento de nomes para os objetos `Cache` correspondentes.

`Client` (en-US)

Representa o escopo do cliente de um *service worker*. Um cliente pode ser um documento no contexto de um navegador ou um `SharedWorker` (en-US), o qual é controlado por um *worker* ativo.

`Clients` (en-US)

Representa o container para uma lista de objetos `Client` (en-US). É a principal forma de acessar os clientes na origem atual para o *service worker* ativo.

`ExtendableEvent` (en-US)

Estende a vida dos eventos `install` e `activate` disparados no `ServiceWorkerGlobalScope` (en-US), como parte do ciclo de vida do *service worker*. Isso garante que qualquer evento funcional (como o `FetchEvent` (en-US)) não seja despachado para o `ServiceWorker` (en-US) até que ele conclua as ações em andamento, como por exemplo: atualizar esquemas de banco de dados, apagar caches defasados, etc.

`ExtendableMessageEvent` (en-US)

O objeto de evento do `message`, o qual é disparado em um *service worker* (quando uma mensagem de canal é recebida no `ServiceWorkerGlobalScope` (en-US) a partir de outro contexto) — estende o tempo de vida desses eventos.

`FetchEvent` (en-US)

O parâmetro recebido no *handler* `ServiceWorkerGlobalScope.onfetch`. O `FetchEvent` representa uma ação de descarregamento que é despachada no `ServiceWorkerGlobalScope` (en-US) de um `ServiceWorker` (en-US). Ele contém informações sobre a requisição e a resposta resultante, além de disponibilizar o método `FetchEvent.respondWith()` (en-US), o qual nos permite devolver uma resposta customizada para a página que está sendo controlada.

`InstallEvent` (en-US)

O parâmetro recebido no *handler* `oninstall`. A interface `InstallEvent` representa uma ação de instalação que é despachada no `ServiceWorkerGlobalScope` (en-US) de um `ServiceWorker` (en-US). Como deriva do `ExtendableEvent` (en-US), ele assegura que eventos funcionais, como o `FetchEvent` (en-US), não sejam despachados durante a instalação.

`NavigationPreloadManager` (en-US)

Disponibiliza métodos para gerenciar o pré-carregamento de recursos com um *service worker.*

`Navigator.serviceWorker` (en-US)

Retornar um objeto `ServiceWorkerContainer` (en-US), o qual permite accesso ao registro, remoção, atualização e comunicação com os objetos `ServiceWorker` (en-US) para o documento associado.

`NotificationEvent` (en-US)

O parâmetro recebido no *handler* `onnotificationclick`. A interface `NotificationEvent` representa um evento de *click* em uma notificação que é despachado no `ServiceWorkerGlobalScope` (en-US) de um `ServiceWorker` (en-US).

`ServiceWorker` (en-US)

Representa um *service worker*. Diferentes contextos de navegação (ex: páginas, *workers*, etc.) podem ser associados com o mesmo objeto `ServiceWorker`.

`ServiceWorkerContainer` (en-US)

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` (en-US)

Representa o contexto de execução global de um *service worker*.

`ServiceWorkerMessageEvent` (en-US) 
Deprecated

Representa uma mensagem enviada a um `ServiceWorkerGlobalScope` (en-US). **Vale ressaltar que essa interface está defasada em navegadores modernos. As mensagens de *service worker* agora usam a interface `MessageEvent` (en-US) para manter consistência com outras funcionalidades de messageria da web.**

`ServiceWorkerRegistration` (en-US)

Representa o registro de um *service worker*.

`ServiceWorkerState` (en-US) 
Experimental

Associado com o estado do `ServiceWorker` (en-US).

`SyncEvent` (en-US) 
Non-standard

A interface SyncEvent representa uma ação de sincronização que é despachada no `ServiceWorkerGlobalScope` (en-US) de um ServiceWorker.

`SyncManager` (en-US) 
Non-standard

Disponibiliza uma interface para registrar e listar registros de sincronização.

`WindowClient` (en-US)

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` (en-US), como alguns métodos e propriedades adicionais disponíveis.

Especificações
--------------

| Specification |
| --- |
| Service Workers  |

Compatibilidade com navegadores
-------------------------------

{{Compat}}Veja também
-----------

* ServiceWorker Cookbook
* Using Service Workers (en-US)
* Service workers basic code example
* Is ServiceWorker ready?
* Promises
* Using web workers (en-US)
* Best Practices for using the VARY header