# Web Workers: guia passo a passo para performance

> Web Workers são uma API do navegador que executa JavaScript em uma thread separada da thread principal, evitando travamentos em tarefas pesadas. A implementação exige criar um arquivo de script dedicado, instanciar o worker via new Worker() e trocar dados por postMessage, com atenção à ausência de acesso direto ao DOM.

*Bombou na Web · Tecnologia · 15 de setembro de 2026 · Kelly Nascimento*

Se a página engasga quando o JavaScript faz trabalho pesado, os Web Workers podem ser a saída. Neste guia, você vê o passo a passo para mover tarefas para uma thread separada, com cuidados e um checklist no final.

Talvez você já tenha visto a página congelar: o botão não responde, a animação para, o clique demora. Acontece quando um script pesado ocupa a thread principal do navegador. Os Web Workers existem para tirar esse peso das costas da interface. A ideia é simples: rodar código em segundo plano, sem bloquear o que o usuário vê. Neste guia, você vai seguir um passo a passo para aplicar isso com cautela, entendendo o que ganha e o que evita.

## Passo 1: Entenda o que está travando

Antes de sair movendo código, identifique o gargalo. Abra o DevTools, aba Performance, grave alguns segundos de interação e observe long tasks. Se um trecho de JavaScript passa de 50 ms sem pausa, é candidato a virar worker. Cálculos matemáticos, parsing de arquivos grandes e processamento de imagens costumam se encaixar. Já manipulação direta do DOM não pode ir para o worker.

**Erro comum:** mover qualquer função para o worker sem medir. Isso adiciona complexidade sem ganho real.

## Passo 2: Crie o arquivo do worker

Um worker é um script separado. Crie um arquivo, por exemplo worker.js, e instancie no código principal com new Worker('worker.js'). O worker não acessa window nem document. Ele tem o próprio escopo global, chamado self. Essa separação é o que garante o isolamento, mas também exige que você pense em como os dados vão e voltam.

**Dica:** mantenha o arquivo pequeno e com uma responsabilidade só. Worker que faz tudo vira uma caixa-preta difícil de depurar.

## Passo 3: Troque mensagens com postMessage

A comunicação acontece por eventos. No lado principal, worker.postMessage(dados). No worker, self.onmessage = (evento) => { ... }. Para devolver, self.postMessage(resultado). Os dados são copiados, não compartilhados, a menos que você use transferable objects, como ArrayBuffer. Em volumes grandes, essa cópia pode custar caro.

**Cuidado:** enviar objetos enormes a cada mensagem pode anular o ganho. Prefira lotes menores e estruturas enxutas.

## Passo 4: Trate erros e finalize o worker

Worker também falha. Escute worker.onerror e registre a mensagem. Quando a tarefa terminar, chame worker.terminate() para liberar recursos. Um worker esquecido vivo consome memória sem necessidade. Em páginas de longa duração, isso se acumula.

**Erro comum:** não tratar erro e achar que o worker sumiu. Ele pode estar parado, esperando uma mensagem que nunca chega.

## Passo 5: Meça o antes e o depois

Volte ao DevTools e compare. O tempo de resposta ao clique melhorou? As long tasks diminuíram? Se a interface continua travando, o gargalo pode estar em outro lugar, como renderização ou rede. Nem todo problema de performance é thread principal.

**Dica:** teste em um dispositivo mais lento. O ganho que aparece no seu computador pode não se repetir no celular do usuário.

## Checklist rápido

- Identifiquei a tarefa pesada com o DevTools.
- Criei um arquivo de worker separado.
- Usei postMessage para enviar e receber dados.
- Tratei erros com onerror.
- Finalizei o worker com terminate.
- Comparei a performance antes e depois.

## FAQ

### O que são Web Workers?

São um mecanismo do navegador que permite executar scripts em uma thread separada da principal. Isso evita que tarefas pesadas travem a interface. O worker não acessa o DOM, então serve para cálculos e processamento, não para manipular elementos da página.

### Quando devo usar um Web Worker?

Quando uma tarefa de JavaScript demora mais de 50 ms e não depende do DOM. Exemplos: cálculos complexos, ordenação de grandes listas, processamento de imagens. Se a tarefa é rápida ou mexe na interface, o worker não ajuda.

### Web Workers podem acessar o DOM?

Não. O worker roda em um escopo isolado, sem window nem document. Para atualizar a tela, ele envia o resultado de volta à thread principal por postMessage, e o código principal faz a alteração. Essa separação é intencional.

### Qual a diferença entre postMessage e transferable objects?

postMessage copia os dados enviados. Transferable objects, como ArrayBuffer, transferem a posse sem copiar, o que é mais rápido para volumes grandes. Depois da transferência, o lado que enviou perde o acesso ao objeto. Use quando o volume justificar.

### Web Workers funcionam em todos os navegadores?

O suporte é amplo nos navegadores modernos. Ainda assim, vale verificar o comportamento no ambiente do seu público. Em cenários específicos, como extensões ou contextos restritos, pode haver limitações. Teste antes de depender só do worker.

### Posso usar vários Web Workers ao mesmo tempo?

Sim, é possível criar vários. Cada um roda em sua própria thread, mas todos competem pelos mesmos recursos do dispositivo. Criar workers demais pode piorar a performance. Comece com um e só aumente se a medição indicar necessidade.

Se você chegou até aqui, talvez já tenha uma tarefa em mente. Vale a pena parar pra pensar: o que na sua página realmente precisa de uma thread separada, e o que só parece pesado?

---

Fonte (canonical): https://www.bombounaweb.com.br/tecnologia/web-workers-guia-passo-a-passo-para-performance/
