Visão geral dos workers

Como os web workers e service workers podem melhorar o desempenho do seu site e quando usar um web worker ou um service worker.

Andrew Guan
Andrew Guan
Demián Renzulli
Demián Renzulli

Esta visão geral explica como os Web workers e service workers podem melhorar o desempenho do seu site e quando usar um Web worker ou um service worker. Confira o restante desta série para ver padrões específicos de comunicação da janela e do service worker.

O navegador usa uma única linha de execução (a linha de execução principal) para executar todo o JavaScript em uma página da Web, além de realizar tarefas como renderizar a página e realizar a coleta de lixo. A execução de código JavaScript em excesso pode bloquear a linha de execução principal, atrasando o navegador de realizar essas tarefas e prejudicando a experiência do usuário.

No desenvolvimento de apps iOS/Android, um padrão comum para garantir que a linha de execução principal do app permaneça livre para responder a eventos do usuário é descarregar as operações em outras linhas de execução. Na versão mais recente do Android, bloquear a linha de execução principal por muito tempo gera uma falha no app.

Na Web, o JavaScript foi projetado com base no conceito de uma única linha de execução e não tem os recursos necessários para implementar um modelo de várias linhas de execução como o dos apps, como a memória compartilhada.

Apesar dessas limitações, um padrão semelhante pode ser alcançado na Web usando workers para executar scripts em linhas de execução em segundo plano, permitindo que realizem tarefas sem interferir na linha de execução principal. Workers são um escopo inteiro do JavaScript executado em uma linha de execução separada, sem memória compartilhada.

Nesta postagem, você vai conhecer dois tipos diferentes de workers (web workers e service workers), as semelhanças e diferenças deles e os padrões mais comuns para usá-los em sites de produção.

Diagrama mostrando dois links entre o objeto Window e um worker da Web e um service worker.

Web workers e service workers

Semelhanças

Web workers e service workers são dois tipos de workers disponíveis para sites. Eles têm algumas coisas em comum:

  • Ambas são executadas em uma linha de execução secundária, permitindo que o código JavaScript seja executado sem bloquear a linha de execução principal e a interface do usuário.
  • Eles não têm acesso aos objetos Window e Document, por isso não podem interagir diretamente com o DOM e têm acesso limitado às APIs do navegador.

Diferenças

Pode-se pensar que a maioria das coisas que podem ser delegadas a um Web worker pode ser feita em um service worker e vice-versa, mas há diferenças importantes entre elas:

  • Ao contrário dos Web workers, os service workers permitem interceptar solicitações de rede (por meio do evento fetch) e detectar eventos da API Push em segundo plano (por meio do evento push).
  • Uma página pode gerar vários web workers, mas um único service worker controla todas as guias ativas sob o escopo em que foi registrado.
  • A vida útil do Web worker está estreitamente associada à guia a que ele pertence, enquanto o ciclo de vida do service worker é independente dele. Por esse motivo, fechar a guia em que um Web worker está em execução o encerrará, enquanto um service worker poderá continuar em execução em segundo plano, mesmo quando o site não tiver nenhuma guia ativa aberta.

Casos de uso

As diferenças entre os dois tipos de workers sugerem em quais situações um pode querer usar um ou outro:

Os casos de uso de Web workers estão mais comumente relacionados à transferência de trabalho (como computações pesadas) em uma linha de execução secundária, evitando o bloqueio da interface.

Diagrama mostrando um link do objeto Window para um worker da Web.
  • Exemplo:a equipe que criou o jogo PROXX queria deixar a linha de execução principal o mais livre possível para cuidar da entrada e das animações do usuário. Para isso, usaram workers da Web para executar a lógica do jogo e a manutenção do estado em uma linha de execução separada.
Uma captura de tela do jogo PROXX.

As tarefas de service workers geralmente estão mais relacionadas a atuar como um proxy de rede, processar tarefas em segundo plano e coisas como armazenamento em cache e off-line.

Uma captura de tela do jogo PROXX.

Exemplo:em um PWA de podcast, é possível permitir que os usuários façam o download de episódios completos para ouvi-los off-line. Um service worker e, em especial, a API Background Fetch podem ser usados para essa finalidade. Dessa forma, se o usuário fechar a guia durante o download do episódio, a tarefa não precisará ser interrompida.

Uma captura de tela de um PWA de podcast.
A interface é atualizada para indicar o progresso de um download (à esquerda). Graças aos service workers, a operação pode continuar em execução quando todas as guias forem fechadas (à direita).

Ferramentas e bibliotecas

A comunicação de janela e worker pode ser implementada usando diferentes APIs de nível inferior. Felizmente, existem bibliotecas que abstraem esse processo, cuidando dos casos de uso mais comuns. Nesta seção, vamos abordar duas delas que cuidam da janela para Web workers e service workers, respectivamente: Comlink e Workbox.

Uma captura de tela do jogo PROXX.

Comlink é uma pequena biblioteca RPC que cuida de muitos detalhes subjacentes ao criar sites que usam Web Workers. Ele foi usado em sites como PROXX e Squoosh. Confira um resumo das motivações e exemplos de código neste link (em inglês).

Workbox

Workbox é uma biblioteca conhecida para criar sites que usam service workers. Ele empacota um conjunto de práticas recomendadas sobre recursos como armazenamento em cache, off-line, sincronização em segundo plano etc. O módulo workbox-window oferece uma maneira conveniente de trocar mensagens entre o service worker e a página.

Próximas etapas

O restante desta série se concentra em padrões de comunicação de janela e service worker:

  • Guia imperativo de armazenamento em cache: chamar um service worker da página para armazenar recursos em cache com antecedência (por exemplo, em cenários de pré-busca).
  • Atualizações de transmissão: chamar a página do service worker para informar sobre atualizações importantes (por exemplo, quando uma nova versão do site está disponível).
  • Comunicação bidirecional: delegar uma tarefa a um service worker (por exemplo, um download pesado) e manter a página informada sobre o progresso.

Para padrões de comunicação de janelas e workers da Web, confira o artigo Usar Web workers para executar o JavaScript fora da linha de execução principal do navegador.