Análises Profundas

WebAssembly explicado: o que ele resolve e onde não ajuda

koboshiCo-founder
·8 min de leitura
WebAssembly explicado: o que ele resolve e onde não ajuda
Resumo

WebAssembly não é um substituto do JavaScript. É um formato compacto de instruções binárias que permite aos navegadores executar código compilado a partir de C, C++, Rust e outras linguagens com velocidade próxima à nativa. Este artigo explica as limitações de aplicativos web escritos apenas em JavaScript, o que o WebAssembly resolve, seus prós e contras reais, casos de uso comuns e por que a conversão de HEIC no lado do cliente seria impossível sem ele.

Solte uma foto HEIC em um conversor no navegador. O arquivo é apenas um contêiner: dentro dele estão dados de imagem codificados com HEVC — a mesma compressão H.265 usada em vídeos 4K. Seu navegador não tem um decodificador HEVC integrado, e escrever um do zero em JavaScript seria lento, frágil e enorme. O decodificador de que você realmente precisa é o libheif, uma biblioteca C++ mantida pela strukturag. O WebAssembly é o que permite que esse decodificador C++ rode dentro da aba do navegador.

Esse exemplo sozinho já resume a ideia toda. WebAssembly não é uma nova linguagem de programação, nem um substituto do JavaScript. É um formato portátil de instruções binárias e um ambiente de execução em sandbox que roda dentro do navegador, ao lado do JavaScript.

O que é WebAssembly na prática

WebAssembly (Wasm) é um padrão do W3C. Define um formato compacto de instruções binárias e uma máquina virtual baseada em pilha. Normalmente você não escreve Wasm manualmente; compila para Wasm a partir de C, C++, Rust, Go, Zig, C# ou uma lista crescente de outras linguagens. O resultado é um módulo .wasm que o navegador baixa, valida e executa dentro de um sandbox com memória segura.

Todos os principais navegadores suportam WebAssembly desde 2017. O formato do módulo foi projetado para ser:

  • Compacto: binário, então é analisado mais rápido que o código JavaScript equivalente.
  • Rápido: compilado antecipadamente para código de máquina pelo navegador.
  • Seguro: cada módulo recebe uma memória linear isolada com verificações de limite.
  • Independente de linguagem: qualquer linguagem que possa compilar para o conjunto de instruções Wasm pode rodar na web.

Os limites da web tradicional

JavaScript é uma boa linguagem para interfaces de usuário, requisições de rede e código de integração (glue code). É dinamicamente tipado, tem coleta de lixo (garbage-collected) e é compilado JIT. Essas propriedades o tornam flexível, mas também imprevisível para computação pesada.

Uma pausa na coleta de lixo pode congelar a thread da interface no meio de uma animação. O aquecimento do JIT significa que o mesmo código pode executar a velocidades diferentes em momentos diferentes. Para operações numéricas ou de bits — decodificação de imagens, codificação de vídeo, criptografia, simulação de física, operações grandes com matrizes — JavaScript geralmente é uma ordem de magnitude mais lento que a mesma lógica compilada a partir de C ou Rust.

A outra limitação é o lock-in de ecossistema. Décadas de bibliotecas de imagem, áudio, vídeo e científicas estão escritas em C e C++. Reescrevê-las em JavaScript não é uma maneira realista de trazer esse recurso para a web.

Por que WebAssembly existe

Wasm foi criado para resolver dois problemas ao mesmo tempo:

  1. Executar código nativo existente no navegador sem reescrevê-lo em JavaScript.
  2. Dar aos aplicativos web uma camada de execução previsível e de alto desempenho para tarefas para as quais o JavaScript nunca foi projetado.

Ele é explicitamente um complemento do JavaScript, não um sucessor. O DOM, a pilha de rede e a maioria das APIs ainda são controlados pelo JavaScript. Wasm cuida da computação isolada; JavaScript cuida da orquestração.

O que WebAssembly resolve

  • Cargas intensivas em CPU: decodificação de imagens, transcodificação de vídeo, execução de física, criptografia de dados.
  • Desempenho previsível: sem coletor de lixo, sem curva de aquecimento do JIT.
  • Reutilização de código: trazer bibliotecas consolidadas como libheif, FFmpeg, SQLite e OpenCV para o navegador.
  • Privacidade: dados sensíveis podem ser processados localmente em vez de enviados para um servidor.
  • Execução offline: depois que o módulo .wasm é baixado, ele executa sem precisar voltar à rede.

Prós e contras

AspectoVantagemLimitação
DesempenhoVelocidade próxima à nativa para tarefas numéricas e limitadas por memóriaNão é mais rápido que o nativo; ainda limitado pelo navegador e dispositivo
PortabilidadeUm módulo roda em qualquer navegador e sistema operacionalRequer um host JavaScript para o DOM e a maioria das APIs do navegador
SegurançaMemória linear em sandbox com verificações de limiteVulnerável a canais laterais no estilo Spectre como qualquer código de navegador
EcossistemaReutiliza bases de código existentes em C/C++/RustA interoperabilidade com JavaScript adiciona complexidade e overhead
InicializaçãoBinário analisado rapidamenteO download e a instanciação do módulo podem ser grandes no primeiro carregamento

A conclusão honesta: Wasm torna o navegador capaz de executar tarefas que não conseguia executar antes, mas não remove as restrições de rodar no dispositivo de um usuário.

Casos de uso comuns

WebAssembly se tornou a resposta padrão quando um aplicativo web precisa fazer o trabalho pesado localmente:

  • Edição de imagem e vídeo: Figma, Photopea e ferramentas similares usam Wasm para renderização e efeitos.
  • Transcodificação de vídeo: FFmpeg.wasm executa o FFmpeg dentro do navegador para conversão de formatos.
  • Reconhecimento óptico de caracteres: Tesseract.js porta o motor OCR Tesseract para Wasm.
  • Jogos: Unity, Godot e Unreal Engine podem exportar para Wasm para jogos baseados em navegador.
  • Análise de dados: Pyodide traz Python e pacotes científicos; sql.js executa SQLite no navegador.
  • Inferência de aprendizado de máquina: ONNX Runtime Web usa um backend Wasm para inferência em CPU.
  • Visualizadores de CAD e 3D: kernels de geometria complexa que antes eram apenas para desktop.
  • Criptografia: hashing, criptografia e provas de conhecimento zero executadas no lado do cliente.

Bibliotecas comuns baseadas em WebAssembly

BibliotecaOrigemO que faz
heic-tolibheif via EmscriptenDecodifica imagens HEIC/HEIF e converte para JPEG, PNG ou bitmap no navegador.
FFmpeg.wasmFFmpeg via EmscriptenTranscodificação, remuxing e filtragem de áudio/vídeo inteiramente no lado do cliente.
Tesseract.jsTesseract OCR via EmscriptenReconhece texto a partir de imagens no navegador.
sql.jsSQLite via EmscriptenExecuta um motor de banco de dados SQLite completo no navegador usando um arquivo em memória.
PyodideCPython via EmscriptenExecuta Python e pacotes como NumPy, Pandas e SciPy sem um backend.
ONNX Runtime WebONNX Runtime via EmscriptenExecuta modelos de aprendizado de máquina ONNX em CPU (Wasm) ou GPU (WebGL/WebGPU).

Cada item da tabela segue o mesmo padrão: pegar um projeto nativo consolidado, compilá-lo para Wasm e oferecer uma API JavaScript por cima. Esse é o valor real do WebAssembly na prática.

Por que a conversão online de HEIC para JPG/PNG/WebP precisa do WebAssembly

HEIC é um contêiner, não um codec. Os dados reais da imagem são codificados com HEVC, que é computacionalmente custoso e sujeito a patentes. Nenhum navegador inclui um decodificador HEVC nativo que páginas web possam usar. A conversão do lado do servidor é a alternativa óbvia, mas exige o upload das fotos do usuário.

A alternativa é levar o libheif — o mesmo decodificador usado por ferramentas de desktop — compilado para WebAssembly. Quando você usa nosso conversor de HEIC para JPG, a decodificação acontece no seu navegador:

  1. O arquivo é validado lendo a assinatura da caixa ftyp.
  2. O módulo Wasm do libheif decodifica o bitstream HEVC localmente.
  3. O bitmap decodificado é escrito em um canvas e exportado como JPEG.

O mesmo módulo é usado no conversor de HEIC para PNG para saída sem perdas com transparência e no conversor de HEIC para WebP para tamanhos otimizados para a web. Sem upload, sem processamento no servidor e nenhum terceiro tem acesso à imagem.

Esse fluxo só funciona porque o WebAssembly pode executar um decodificador de imagens de verdade. JavaScript sozinho não consegue processar HEVC em tempo razoável; um upload para o servidor anularia a promessa de privacidade. O Wasm é o que torna isso possível.

O futuro do WebAssembly

Wasm está indo além do navegador. A WebAssembly System Interface (WASI) define uma interface de sistema portátil que permite que módulos Wasm rodem em servidores, edge workers e dispositivos IoT. Runtimes como Wasmtime, Wasmer e WasmEdge já estão em produção fora do navegador.

A proposta do Component Model permitirá que módulos Wasm exponham interfaces tipadas e se componham como bibliotecas, facilitando conectar um módulo Rust a um host Python ou a um serviço Go. WebAssembly GC adiciona melhor suporte para linguagens gerenciadas como Java e Kotlin. Nada disso é sobre substituir o JavaScript no navegador — é sobre tornar o Wasm um alvo de runtime universal e leve.

A mesma tendência é visível no navegador: mais recursos nativos migrados para o cliente, mais ferramentas que preservam a privacidade e mais bibliotecas que antes eram apenas para desktop rodando em uma aba. WebAssembly não é um recurso que os usuários notem, mas é cada vez mais o que permite que cargas de trabalho exigentes rodem na web.

Mais posts do blog