Tentando descobrir o que é um trabalhador de serviços? Você não está sozinho!
A Service Worker é um script que executa em segundo plano, em uma thread separada da interface do navegador. O cache de um técnico de serviços torna possível que um site funcione offline. Eles são o poder técnico que eleva um site a um aplicativo web progressivo. Eles permitem a integração profunda da plataforma, como cache rico, notificações push e sincronização em segundo plano.
Os trabalhadores de serviço são projetados para ser uma plataforma extensível, recursos adicionais estão sendo planejados atualmente.
Não podem acessar o DOM, mas podem interceptar todas as solicitações de rede. Isto permite aos desenvolvedores a oportunidade de controlar como as requisições são tratadas, fornecendo uma maneira rica de fazer os sites funcionarem offline.
Os trabalhadores de serviços são chamados de alteradores de jogo para a web. Eu não acho que isso seja um simples exagero, pois eles habilitam muitas capacidades muito necessárias e tornam a arquitetura central que usei durante anos nativa.
Service Workers soam incrível!
Esta é a tecnologia chave ou a API web moderna por trás das Aplicações Web Progressivas. Sem um trabalhador de serviços um site é apenas um site, adicione um trabalhador de serviços e agora você tem uma aplicação.
Existem alguns recursos-chave sobre os trabalhadores de serviços que você precisa entender:
- Um Service Worker é um arquivo JavaScript
- Eles executam em uma thread separada do UI
- Não podem acessar o DOM diretamente
- Existe um ciclo de vida ou série de eventos pelos quais um service worker flui para se tornar ativo, explicado mais tarde
- Só estão ao vivo enquanto estão sendo usados, por isso não há tensão de bateria
- São isolados para a origem ou domínio com que estão registados
- Os trabalhadores de serviço requerem HTTPS
- Podem enviar mensagens de e para a IU
- Não requerem uma página web aberta para funcionar
- São suportados por todos os principais navegadores, incluindo iOS Safari
- São semelhantes aos trabalhadores da Web, mas melhores em muitos aspectos
- Como funcionam os trabalhadores dos serviços?
- Extensibilidade do trabalhador de serviço
- Ciclo de vida do trabalhador de serviço
- Quanto tempo dura o trabalhador de serviço?
- Como eu verifico se um trabalhador de serviço está registrado?
- Como faço para cancelar o registro de um trabalhador de serviço
- Caching de trabalhador de serviço
- Como faço para atualizar o cache do meu trabalhador de serviço
- Que Browsers suportam os trabalhadores de serviço?
- Qual é a diferença entre um trabalhador de serviços e um Web Worker
- O que um trabalhador de serviços não pode fazer
Como funcionam os trabalhadores de serviços?
Um trabalhador de serviços senta-se entre o navegador e a rede, agindo como um servidor proxy, lidando com uma coleção de tarefas não centradas na interface do usuário. Eles são guiados por eventos e vivem fora do processo do navegador, permitindo-lhes trabalhar sem uma sessão ativa do navegador. O funcionário de serviço é um script que executa em um thread, separado da interface de usuário. Isto permite que o service worker execute tarefas não-UI, fazendo com que um website tenha um melhor desempenho.
Service workers terminam quando não estão em uso e são restaurados quando necessário, isto os impede de sobrecarregar a CPU e drenar as baterias. Eles atuam como um proxy de rede programável, ou intermediário entre o navegador e a rede, capacitando os desenvolvedores a projetar como as solicitações de rede são tratadas.
A primeira potência que um trabalhador de serviços traz para um site é a capacidade de habilitar recursos offline com controle granular. Isto é feito com uma API de cache rica e interceptando todas as solicitações de rede antes que elas saiam.
O cache não só permite experiências offline, como também os sites podem ser carregados instantaneamente quando recuperados do cache. O cache de trabalhadores de serviço torna a rede um aprimoramento progressivo, ou não necessário para tornar o site utilizável.
Service Worker Extensibility
Uma característica subestimada dos trabalhadores de serviço é sua extensibilidade Os trabalhadores de serviço são projetados para ser o backbone que suporta funcionalidades adicionais. Os dois primeiros recursos de envio em navegadores são notificações push nativas e sincronização de fundo. Mais novas APIs estão sendo debatidas atualmente e devem começar a aparecer nos navegadores no futuro próximo.
Os trabalhadores de serviços vivem em sua própria thread e não têm acesso ao DOM. Eles também têm seu próprio escopo global, referido ao uso do objeto ‘self’.
O também requer um site é servido usando HTTPS. Este requisito é devido aos poderosos recursos que os trabalhadores do serviço oferecem. HTTPS previne muitos ataques comuns. Hoje todos os sites devem ser servidos usando HTTPS, pois as barreiras para implementar foram levantadas e a quantidade mínima de segurança que oferecem.
Também são assíncronos. Isto significa que todas as APIs suportam promessas. Isto também significa que certas APIs e funções não são acessíveis para os trabalhadores dos serviços. A mais notável é a localStorage. Ao invés disso, os dados devem ser armazenados usando IndexedDB.
Service Worker Life Cycle
Antes de mergulhar nesses grandes recursos do service worker, os desenvolvedores precisam entender o ciclo de vida.
Um service worker precisa ser registrado por um website. Como alguns navegadores ainda não suportam trabalhadores de serviços, você deve realizar uma verificação de recursos antes de registrar um trabalhador de serviços. Isto é feito verificando a presença de ‘serviceWorker’ no navigator.
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(function(registration) { // Registration was successful }) .catch(function(err) { // registration failed :( }); }
Para registrar o service worker ligue para navigator.serviceWorker.register. Passar o caminho para o trabalhador de serviço. A função register retorna uma promessa.
Se a promessa for bem sucedida, retorna uma referência ao objeto de registro do prestador de serviços. A partir daí você pode executar tarefas UI específicas conforme necessário.
Standard Service Worker Events
- install
- activate
- fetch
- push (não suportado pelo Safari)
- sync (ainda não suportado pela maioria dos navegadores)
Quando um funcionário de serviço é registrado o evento “install”. Neste evento a tarefa mais comum a realizar é chamada de pre-caching.
Pre-caching é onde uma lista pré-definida de arquivos de ativos necessários para formar uma página ou site, e adicioná-los ao cache antes de serem solicitados. Isso aproveita o cache do funcionário do serviço para persistir nessas respostas.
self.addEventListener("install", event => { event.waitUntil( caches.open(preCacheName) .then(function (cache) { return cache.addAll(precache_urls); }) ); });
O evento de instalação só é acionado uma vez no tempo de vida do funcionário do serviço. O evento não será acionado novamente até que o funcionário do serviço seja atualizado.
O próximo evento que dispara como parte do ciclo de vida do registro é ‘ativado’. Quando um funcionário de serviço é instalado, ele não se torna imediatamente ativo. A seqüência natural é um novo funcionário de serviço esperar até que todos os ‘clientes’ do funcionário de serviço sejam fechados.
A razão pela qual os funcionários de serviço são projetados para não assumirem imediatamente é para evitar que eles interrompam a experiência do usuário.
A função SkipWaiting força um funcionário de serviço em espera a se tornar ativo. Isto só deve ser empregado quando você estiver certo de que o novo funcionário de serviço não irá quebrar nenhum cliente existente.
self.skipWaiting();
Após o funcionário de serviço se tornar ativo, o evento ‘activate’ dispara.
self.addEventListener("activate", event => { //on activate event.waitUntil(clients.claim()); });
Este evento é comumente usado para realizar qualquer tarefa de limpeza ou migração. Por exemplo, remover caches legados que possam entrar em conflito com os novos caches de trabalhadores de serviços.
Quanto tempo para os trabalhadores de serviços durar?
Não há nenhuma regra difícil sobre quanto tempo um navegador mantém um trabalhador de serviços funcionando. Internamente o motor do navegador utilizará um conjunto de heurísticas para determinar quando terminar o processo do funcionário de serviço.
Em geral, se uma página da web estiver dormente o processo irá girar para baixo após um minuto ou dois, talvez assim que 30 segundos.
A realidade é que o tempo exato dependerá do hardware, padrões de uso, etc.
A boa notícia é que leva um punhado de milissegundos para ligar um funcionário de serviço. É tão rápido que você realmente não vai notar nenhuma latência. Você também não precisa programar nada de especial para lidar com um cenário sem o técnico de serviço, você só vai trabalhar no local. A magia do melhoramento progressivo.
Como posso verificar se um técnico de serviços está registado?
Existem várias formas de verificar se um técnico de serviços está registado. A mais fácil é chamar o método serviceworkers.getRegistrations.
navigator.serviceWorker.getRegistrations().then(registrations => { console.log(registrations); });
Esse é o código que você pode adicionar ao seu script de páginas para registrar o registro para suporte técnico ou depuração de desenvolvedores.
O método ‘getRegistrations’ retorna um array de todos os trabalhadores de serviço registrados sob o escopo atual ou website.
Se você está apenas registrando o registro no console, seria melhor visualizar a aba Dev Tools ‘Application’. Ele tem um sub-panel que exibe um visual do funcionário de serviço registrado da origem. Você também pode acionar eventos de sincronização em segundo plano e notificações de teste push.
Você também pode excluir o funcionário do serviço, forçar uma atualização e outras gerências gerais que ajudam no desenvolvimento.
O valor real que o getRegistrations oferece é para algum tipo de recurso de suporte de porta traseira. Todos nós sabemos como é tentar ajudar alguém remotamente e você não pode acessar as DevTools para realmente resolver o problema. Às vezes você vai querer algum tipo de página de suporte visual ou modal para fornecer informações sobre o estado da aplicação.
O consumidor médio não saberá como acessar o painel de console do DevTools. Em vez disso você pode criar uma interface de usuário dentro da aplicação para ecoar as propriedades do objeto de registro do trabalhador de serviço.
Como eu desregisto um trabalhador de serviço
Esperançosamente você não encontrará um cenário onde o seu código de trabalhador de serviço tenha criado um bug de experiência de usuário. Caso você faça, há poucas coisas que você pode fazer para remover ou cancelar o registro de um funcionário de serviço.
A maioria dos cenários onde você precisa remover um funcionário de serviço será quando você estiver desenvolvendo a aplicação. Neste caso, você pode usar as DevTools para remover ou excluir o servidor de serviços.
Se você precisar remover ou excluir um funcionário de serviço implantado, fica um pouco mais complicado. Existem maneiras programáticas de tirar você do jam.
Ler mais sobre técnicas de remoção.
Caching de trabalhadores de serviço
A especificação do trabalhador de serviço inclui recursos de cache nativo. Isto substitui o tradicional appCache que tem causado muitos problemas de gerenciamento desde que ele foi criado. O cache do servidor de serviços é muito mais gerenciável.
A API do cache fornece uma camada de persistência que armazena respostas de rede que podem ser consultadas pela requisição correspondente.
A chave para usar o cache do servidor de serviços é o evento ‘fetch’ do servidor de serviços. Esse evento aciona para cada requisição de rede permitindo que você intercepte a requisição e verifique se a resposta foi colocada em cache antes de ir para a rede.
Ao acessar ativos em cache local, você pode renunciar a requisições caras de rede. Isto significa que o site pode funcionar quando não há rede, offline, ou má conectividade de rede, barras baixas ou falsa conectividade celular (conhecida como LiFi).
self.addEventListener("fetch", event => { event.respondWith( fetchFromCache(event) .catch(() => fetch(request) .then(response => addToCache(cacheKey, request, response)) .catch(() => offlineResponse(resourceType, opts)) ) ); });
No exemplo acima a verificação do código é uma resposta que foi previamente colocada em cache. Se assim for, a resposta em cache é retornada. Se não, a requisição é passada para a rede.
Quando a requisição retorna a resposta é colocada em cache e retornada para a UI.
Se a rede falhar a lógica cai de volta para uma resposta offline.
Existem muitas partes móveis sendo usadas no código do exemplo. Eu fornecerei mais detalhes em um artigo de acompanhamento.
Como faço para atualizar o cache do meu assistente de serviço
Um equívoco comum é uma vez que você armazena em cache um pedido de rede para a eternidade. Este não é o caso. Você tem controle completo sobre quando e como o cache é invalidado e atualizado.
Este é um tópico muito complexo e envolvido. Penso que posso detalhar pessoalmente cerca de 3 dúzias de estratégias de cache, todas envolvem uma forma de gerir a invalidação do cache ou de actualizar o cache.
Penso que a chave para a invalidação é determinar ou um tempo para invalidar (tempo para viver) o valor, um manifesto ou um processo de actualização em segundo plano. Mais tarde você pode fazer uma solicitação HEAD para ver se uma atualização foi feita no servidor, comparando o valor do cabeçalho lastt-updated com o tempo em que a resposta foi colocada em cache.
Não há uma resposta única para cada aplicação. Você precisará planejar sua estratégia e estar preparado para se ajustar à medida que você vê como seu aplicativo é utilizado.
Que Browsers suportam os trabalhadores de serviço?
Todos os Browsers modernos suportam os trabalhadores de serviço, pelo menos o cache. Chrome, FireFox e Edge suportam notificações push nativas e Chrome e Edge têm suporte a sincronização de fundo.
Isso significa que os principais recursos de PWA estão disponíveis em todos os dispositivos e navegadores. Push e background sync são melhorias.
Construímos vários aplicativos Web Progressivos que exigiam estratégias sofisticadas de cache offline para permitir que os aplicativos funcionassem offline, mesmo no iOS. Estas aplicações requerem que todas as solicitações, mesmo as ações POST, PUT e DELETE sejam colocadas em cache em uma fila. Nós fizemos essa sincronização de aplicativos mesmo no iOS quando as conexões eram conhecidas por estarem disponíveis.
Qual é a diferença entre um trabalhador de serviços e um trabalhador da Web
Os trabalhadores de serviços e os trabalhadores da Web são ferramentas similares. Ambos executam processos em uma thread separada da interface do usuário. A diferença real está no contexto real de uso.
Nem tem acesso ao objeto DOM ou à janela. Eles são melhores para tarefas de nível médio ou longo, tarefas de processo intensivo.
Os trabalhadores web só são executados quando uma página web está aberta e uma tarefa é acionada a partir de um script na página.
Um trabalhador de serviço também pode executar quando uma página está aberta, mas também pode ser acionado por um evento da plataforma como uma notificação push. Uma página web não precisa estar aberta para que um service worker execute.
Service workers também atuam como um proxy entre a rede e a interface do usuário. Se uma página estiver sendo usada (o cenário mais comum) todas as solicitações de rede HTTPS passam pelo service worker como você aprendeu na seção de cache.
Comunicação entre a IU e ambos os workers é feita usando o método postMessage e o evento da mensagem. Se você fez alguma programação multi-threaded este modelo é muito familiar.
O que um trabalhador de serviço não pode fazer
Os trabalhadores de serviço não podem acessar o objeto janela
O objeto janela executa na thread UI, separado da thread do trabalhador de serviço. Isto significa que um trabalhador de serviço não pode manipular directamente elementos DOM. O funcionário de serviço e a janela podem se comunicar através do método pós-Mensagem. Isto permite que as mensagens sejam passadas para a frente e para trás. Você precisará ter lógica de cada lado para processar as mensagens e acionar fluxos de trabalho diferentes.
Service Workers Require HTTPS
Because Service Workers have so much power they are so enabled if the page is served using HTTPS. Isso garante um nível de segurança que permite ao trabalhador de serviço fazer as coisas para as quais ele foi projetado.
Over HTTP o service worker seria suscetível a ataques do homem no meio. Os desenvolvedores podem trabalhar em localhost, o que nos impede de instalar um certificado TLS local.
Em outras palavras, a resposta para um service worker trabalhar em HTTP é não. O site ainda renderizará, mas o service worker não se registra e não é executado.
Are Only Asynchronous
Service workers are asynchronous, o que significa que eles usam e dependem de Promises e APIs que usam Promises. Isto significa que APIs síncronas como XHR e localStorage não estão disponíveis para um trabalhador de serviços. Nunca tema, você pode usar o Fetch API (que substituiu o XHR) e o IndexedDB. A maioria das APIs que não interagem diretamente com o objeto window estão acessíveis em um service worker.