Web Workers JavaScript: Guia Completo Passo a Passo
Se a sua página trava quando você processa um array grande ou gera um relatório, o problema é a thread principal. Ela cuida da interface, e qualquer cálculo longo bloqueia tudo. A solução é o Web Worker, uma thread separada que roda em segundo plano. Neste guia, você vai criar um worker do zero, entender como ele se comunica com a página e ver os erros que todo mundo comete no começo. Você vai precisar de um editor de texto, um navegador moderno e um arquivo HTML básico para testar. Nada de servidor, funciona direto no arquivo local.
Passo 1: Crie o arquivo do worker
O worker é um arquivo JavaScript separado. Crie um arquivo chamado worker.js. Dentro dele, você vai escutar mensagens vindas da thread principal usando o evento onmessage. Quando uma mensagem chega, você processa os dados e envia o resultado de volta. No nosso exemplo, vamos calcular a soma de um array.
// worker.js self.onmessage = function(e) { const numeros = e.data; const soma = numeros.reduce((acc, atual) => acc + atual, 0); self.postMessage(soma); };
Erro comum: esquecer o self antes de onmessage. Sem ele, o worker não escuta nada. Dentro do worker, self representa o escopo global do próprio worker.
Passo 2: Instancie o worker na página principal
No seu arquivo HTML ou script principal, crie uma nova instância do worker passando o caminho do arquivo.
const meuWorker = new Worker('worker.js');
A partir daí, você pode enviar dados para ele com postMessage e receber respostas com onmessage.
meuWorker.postMessage([1, 2, 3, 4, 5]); meuWorker.onmessage = function(e) { console.log('Resultado:', e.data); };
Dica: verifique se o arquivo do worker existe no caminho certo. Um erro de digitação no nome ou na pasta faz o navegador lançar uma exceção silenciosa no console.
Passo 3: Encerre o worker quando terminar
Um worker consome memória enquanto está ativo. Se você não precisa mais dele, chame o método terminate().
meuWorker.terminate();
Erro comum: deixar workers abertos em páginas de longa duração. Em uma SPA, isso pode causar vazamento de memória e lentidão gradual. Sempre termine o worker no unload ou quando a tarefa acabar.
Passo 4: Trate erros dentro do worker
O worker pode falhar. Use o evento onerror no objeto principal para capturar exceções.
meuWorker.onerror = function(e) { console.error('Erro no worker:', e.message); };
Dica: dentro do worker, use try...catch para tratar erros de lógica e enviar uma mensagem de erro customizada via postMessage. Assim, você sabe o que aconteceu sem olhar o console.
Checklist rápido
Você criou um arquivo de worker com onmessage e postMessage. Instanciou o worker na página com new Worker(). Enviou dados, recebeu o resultado e terminou o worker com terminate(). Se você fez tudo isso, já tem um fluxo básico de processamento em segundo plano.
FAQ
Web Workers funcionam em todos os navegadores?
Não. Eles são suportados em todos os navegadores modernos, mas o Internet Explorer 9 e versões anteriores não têm suporte. Para aplicações críticas, verifique a compatibilidade com typeof Worker !== 'undefined' antes de usar.
Posso acessar o DOM dentro de um worker?
Não. O worker não tem acesso ao objeto document. Ele só pode usar APIs como fetch, XMLHttpRequest, IndexedDB e postMessage. Para atualizar a interface, você precisa enviar o resultado de volta para a thread principal.
Web Workers são iguais a Service Workers?
Não. Service Workers atuam como proxy de rede, interceptando requisições e permitindo funcionalidade offline. Web Workers são para processamento paralelo. Cada um tem um propósito distinto.
Qual é a diferença entre worker dedicado e compartilhado?
Um worker dedicado é criado por uma única página e só ela usa. Um worker compartilhado pode ser acessado por múltiplas páginas do mesmo domínio. A maioria dos casos usa o dedicado, que é mais simples.
Como envio objetos complexos para um worker?
Você pode enviar objetos e arrays via postMessage. Eles são serializados com o algoritmo de structured clone. Funções não podem ser enviadas. Se precisar de transferência de grandes buffers, use ArrayBuffer com a opção de transferência.
O que acontece se eu criar muitos workers?
O navegador limita o número de workers por página. Esse limite varia, mas em geral fica entre 4 e 16. Criar muitos pode degradar a performance. Use um pool de workers para tarefas concorrentes.
Agora você tem o caminho para tirar o peso da thread principal. Teste com um cálculo real, como a soma de um array de um milhão de elementos. A interface vai continuar responsiva. Esse é o ganho prático de usar Web Workers.