spinny:~/writing $ vim webassembly-wasm-complete-guide.md
1~2WebAssembly (WASM) comecou como uma forma de executar C++ no navegador. Em 2026, ele roda em todo lugar - navegadores, servidores, redes edge, dispositivos embarcados - e alimenta algumas das aplicacoes mais exigentes da web. O motor de renderizacao do Figma, o Adobe Photoshop na web, o processamento de video do Google Meet e a plataforma de computacao edge da Cloudflare funcionam todos sobre WebAssembly.3~4O Chrome Platform Status situa o WASM em aproximadamente 5,5% de todos os carregamentos de pagina no Chrome no inicio de 2026, acima dos 4,5% do ano anterior. Com o WASM 3.0 tornado padrao W3C e o WASI amadurecendo rumo a versao 1.0, o ecossistema atingiu um ponto de virada.5~6Este guia cobre tudo o que voce precisa saber para comecar a desenvolver com WebAssembly.7~8## O que e WebAssembly?9~10WebAssembly e um formato de instrucoes binarias projetado como alvo de compilacao. Voce escreve codigo em uma linguagem de alto nivel (Rust, C, C++, Go, Kotlin), compila para `.wasm` e executa em qualquer ambiente que tenha um runtime WASM - navegadores, Node.js, Cloudflare Workers, Wasmtime ou Wasmer.11~12```mermaid13graph LR14 Rust[Rust / C / C++] --> Compiler[Compiler]15 Compiler --> WASM[.wasm Binary]16 WASM --> Browser[Browser V8/SpiderMonkey]17 WASM --> Server[Server Wasmtime]18 WASM --> Edge[Edge Cloudflare Workers]19 WASM --> Embedded[Embedded WAMR]20```21~22### Como funciona23~24WASM e uma **maquina virtual baseada em pilha**. As funcoes empilham e desempilham valores em uma pilha de operandos. O runtime host (V8 no Chrome, SpiderMonkey no Firefox) compila JIT o bytecode WASM em codigo de maquina nativo, por isso o desempenho e quase nativo.25~26Caracteristicas principais:27~28- **Execucao em sandbox**: os modulos WASM so podem acessar recursos que o host concede explicitamente. Sem acesso ao sistema de arquivos, a rede ou ao sistema operacional, a menos que seja permitido. Isso e fundamentalmente diferente do codigo nativo.29- **Memoria linear**: um unico `ArrayBuffer` contiguo compartilhado entre WASM e o host. Dados complexos (strings, structs) sao passados escrevendo na memoria e compartilhando um ponteiro.30- **Tipos limitados**: WASM suporta nativamente apenas quatro tipos: `i32`, `i64`, `f32`, `f64`. Todo o resto (strings, arrays, objetos) requer codificacao atraves da memoria linear ou do Component Model.31- **Portavel**: o mesmo binario `.wasm` roda em qualquer plataforma com um runtime WASM, sem recompilacao.32~33### WASM vs JavaScript34~35WASM nao substitui JavaScript. Ele o complementa.36~37| Aspecto | JavaScript | WebAssembly |38|---------|-----------|-------------|39| **Parsing** | Parsing + compilacao em tempo de execucao | Binario pre-compilado, apenas decodificacao |40| **Velocidade de execucao** | Otimizado JIT, variavel | Quase nativo, constante |41| **Inicializacao** | Rapida para scripts pequenos | Decodificacao rapida, previsivel |42| **Acesso ao DOM** | Direto | Indireto (atraves de glue JS) |43| **Ideal para** | UI, manipulacao do DOM, tratamento de eventos | Computacao intensiva em CPU |44| **Garbage collection** | Integrado | WasmGC (novo), ou manual |45~46Use JavaScript para interface de usuario e trabalho com o DOM. Use WASM para computacao pesada: processamento de imagens, codificacao de video, simulacoes fisicas, criptografia, parsing de dados.47~48## WASM 3.0: as novidades49~50WebAssembly 3.0 tornou-se padrao W3C em setembro de 2025, padronizando nove funcionalidades que estavam em desenvolvimento ha anos.51~52| Funcionalidade | O que permite |53|----------------|--------------|54| **WasmGC** | Garbage collection nativa no WASM. Linguagens gerenciadas (Java, Kotlin, Dart) podem compilar para WASM sem incluir seu proprio runtime GC. Suportado no Chrome 119+, Firefox 120+, Safari 18.2+. |55| **Exception Handling** | `try`/`catch` nativos no WASM. Antes, as excecoes exigiam ida e volta custosas ao JavaScript. |56| **Tail Calls** | Permite recursao eficiente sem stack overflow. Fundamental para linguagens funcionais. |57| **Relaxed SIMD** | Instrucoes vetoriais de 128 bits para processamento paralelo de dados. Permite otimizacoes especificas de hardware. |58| **Memory64** | Ultrapassa o limite de 4GB de memoria linear. Necessario para processamento de dados em larga escala. |59| **Multi-memory** | Multiplas regioes de memoria independentes em um unico modulo. |60~61A mais impactante e o **WasmGC**. Antes dele, compilar Java ou Kotlin para WASM significava incluir um garbage collector completo como parte do binario, inflando o tamanho dos arquivos. Agora o GC do navegador gerencia a memoria para os modulos WASM, assim como faz para JavaScript.62~63## WASI: WebAssembly alem do navegador64~65WASM no navegador e poderoso, mas o **WASI (WebAssembly System Interface)** e o que torna o WASM um runtime universal. O WASI fornece interfaces padronizadas para recursos do sistema - arquivos, rede, relogios, numeros aleatorios - permitindo que modulos WASM funcionem fora do navegador.66~67```mermaid68graph TD69 subgraph "Browser"70 B[WASM Module] --> Web[Web APIs\nDOM, Fetch, Canvas]71 end72~73 subgraph "Server / Edge / Embedded"74 S[WASM Module] --> WASI[WASI Interfaces]75 WASI --> FS[wasi:filesystem]76 WASI --> Net[wasi:sockets]77 WASI --> HTTP[wasi:http]78 WASI --> Clock[wasi:clocks]79 WASI --> Rand[wasi:random]80 end81```82~83O WASI Preview 2 (a versao estavel atual) define estas interfaces:84~85- `wasi:filesystem` - operacoes com arquivos via handles de capacidade (nao os descritores de arquivo tradicionais)86- `wasi:sockets` - rede TCP/UDP87- `wasi:http` - tratamento de requisicoes/respostas HTTP88- `wasi:clocks` - relogio do sistema, relogio monotonico89- `wasi:random` - aleatoriedade criptografica90- `wasi:cli` - argumentos de linha de comando, variaveis de ambiente, stdio91~92O principio chave e a **seguranca baseada em capacidades**: um modulo WASM nao pode acessar o sistema de arquivos a menos que o host conceda explicitamente um handle para um diretorio especifico. Isso torna o WASI fundamentalmente mais seguro do que executar executaveis nativos.93~94### O caminho para o WASI 1.095~96O WASI 0.3.0 (adicionando primitivas async/concorrencia) e esperado em 2026, com o WASI 1.0 a seguir. A principal adicao e o async integrado a linguagem com I/O streaming de copia zero.97~98## O Component Model99~100Os modulos WASM basicos so podem trocar numeros. O **Component Model** resolve essa limitacao adicionando um sistema de tipos rico e uma camada de composabilidade sobre o WASM.101~102### WIT (WebAssembly Interface Types)103~104WIT e uma linguagem de definicao de interfaces que permite aos componentes declarar suas importacoes e exportacoes com tipos ricos - strings, registros, listas, variantes, enumeracoes - nao apenas `i32` e `f64`.105~106```wit107// calculator.wit108package myorg:calculator@1.0.0;109~110interface operations {111 record calculation {112 expression: string,113 result: f64,114 timestamp: u64,115 }116~117 add: func(a: f64, b: f64) -> f64;118 multiply: func(a: f64, b: f64) -> f64;119 history: func() -> list<calculation>;120}121~122world calculator {123 export operations;124}125```126~127As toolchains como `wit-bindgen` geram bindings especificos da linguagem a partir de arquivos WIT. Um componente Rust e um componente Python podem trocar strings, registros e listas atraves de contratos WIT sem que nenhuma das partes conheca a linguagem de implementacao da outra.128~129## Construindo seu primeiro modulo WASM com Rust130~131Rust tem as ferramentas WASM mais maduras. Vamos construir um exemplo pratico: um modulo de processamento de imagens que roda no navegador.132~133### Configuracao134~135```bash136# Install the WASM target for Rust137rustup target add wasm32-unknown-unknown138~139# Install wasm-pack (builds Rust to WASM + generates JS bindings)140cargo install wasm-pack141~142# Create a new library project143cargo new --lib image-processor144cd image-processor145```146~147### Configurar o Cargo.toml148~149```toml150[package]151name = "image-processor"152version = "0.1.0"153edition = "2021"154~155[lib]156crate-type = ["cdylib"]157~158[dependencies]159wasm-bindgen = "0.2"160```161~162### Escrever o codigo Rust163~164```rust165// src/lib.rs166use wasm_bindgen::prelude::*;167~168/// Convert an image buffer to grayscale.169/// Input: RGBA pixel data as a flat u8 array (4 bytes per pixel).170/// Output: Modified in place for zero-copy performance.171#[wasm_bindgen]172pub fn grayscale(pixels: &mut [u8]) {173 for chunk in pixels.chunks_exact_mut(4) {174 let r = chunk[0] as f32;175 let g = chunk[1] as f32;176 let b = chunk[2] as f32;177 // ITU-R BT.709 luminance coefficients178 let gray = (0.2126 * r + 0.7152 * g + 0.0722 * b) as u8;179 chunk[0] = gray;180 chunk[1] = gray;181 chunk[2] = gray;182 // chunk[3] is alpha, leave unchanged183 }184}185~186/// Adjust brightness of an image.187/// factor > 1.0 brightens, < 1.0 darkens.188#[wasm_bindgen]189pub fn adjust_brightness(pixels: &mut [u8], factor: f32) {190 for chunk in pixels.chunks_exact_mut(4) {191 chunk[0] = ((chunk[0] as f32 * factor).min(255.0)) as u8;192 chunk[1] = ((chunk[1] as f32 * factor).min(255.0)) as u8;193 chunk[2] = ((chunk[2] as f32 * factor).min(255.0)) as u8;194 }195}196~197/// Invert all colors in the image.198#[wasm_bindgen]199pub fn invert(pixels: &mut [u8]) {200 for chunk in pixels.chunks_exact_mut(4) {201 chunk[0] = 255 - chunk[0];202 chunk[1] = 255 - chunk[1];203 chunk[2] = 255 - chunk[2];204 }205}206~207/// Calculate the average brightness of an image (0-255).208#[wasm_bindgen]209pub fn average_brightness(pixels: &[u8]) -> f32 {210 let mut total: f64 = 0.0;211 let pixel_count = pixels.len() / 4;212 for chunk in pixels.chunks_exact(4) {213 let luminance = 0.2126 * chunk[0] as f64214 + 0.7152 * chunk[1] as f64215 + 0.0722 * chunk[2] as f64;216 total += luminance;217 }218 (total / pixel_count as f64) as f32219}220```221~222### Build223~224```bash225wasm-pack build --target web226```227~228Isso produz um diretorio `pkg/` com:229- `image_processor_bg.wasm` - o binario WASM compilado230- `image_processor.js` - codigo glue JavaScript com definicoes TypeScript231- `package.json` - pronto para publicar no npm232~233### Uso em JavaScript234~235```html236<!DOCTYPE html>237<html>238<head><title>WASM Image Processor</title></head>239<body>240 <canvas id="canvas" width="800" height="600"></canvas>241 <button onclick="applyGrayscale()">Grayscale</button>242 <button onclick="applyBrightness()">Brighten</button>243 <button onclick="applyInvert()">Invert</button>244~245 <script type="module">246 import init, { grayscale, adjust_brightness, invert } from "./pkg/image_processor.js";247~248 let ctx;249 let imageData;250~251 async function setup() {252 await init();253 const canvas = document.getElementById("canvas");254 ctx = canvas.getContext("2d");255~256 // Load an image onto the canvas257 const img = new Image();258 img.onload = () => {259 ctx.drawImage(img, 0, 0);260 imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);261 };262 img.src = "photo.jpg";263 }264~265 window.applyGrayscale = () => {266 grayscale(imageData.data);267 ctx.putImageData(imageData, 0, 0);268 };269~270 window.applyBrightness = () => {271 adjust_brightness(imageData.data, 1.3);272 ctx.putImageData(imageData, 0, 0);273 };274~275 window.applyInvert = () => {276 invert(imageData.data);277 ctx.putImageData(imageData, 0, 0);278 };279~280 setup();281 </script>282</body>283</html>284```285~286O ponto chave: `imageData.data` e um `Uint8ClampedArray` apoiado por um `ArrayBuffer`. Quando passado para o WASM, compartilha a mesma memoria - sem copias. A funcao Rust modifica os pixels diretamente, e o lado JavaScript ve as mudancas imediatamente.287~288## Nivel mais baixo: instanciacao manual do WASM289~290Se voce nao quiser usar o `wasm-bindgen`, pode instanciar modulos WASM diretamente:291~292```javascript293const response = await fetch("calculator.wasm");294const { instance } = await WebAssembly.instantiateStreaming(response, {295 env: {296 // Functions the WASM module can call297 log_result: (value) => console.log("Result:", value),298 },299});300~301// Call exported functions302const { add, multiply } = instance.exports;303console.log(add(5, 3)); // 8304console.log(multiply(4, 7)); // 28305```306~307Isso e util quando voce quer overhead minimo e nao precisa de interoperabilidade avancada entre tipos.308~309## Desempenho: WASM vs JavaScript310~311Benchmarks reais mostram aceleracoes significativas para tarefas intensivas em CPU:312~313| Tarefa | JavaScript | WASM | Aceleracao |314|--------|-----------|------|------------|315| Processamento de imagem 4K | 180ms | 8ms (com SIMD) | 22x |316| Redimensionamento de imagem (4K) | 250ms | 45ms | 5,5x |317| Simulacao fisica (10K entidades) | Frames perdidos | 60fps fluidos | ~10x |318| Parsing JSON (carga grande) | 12ms | 3ms | 4x |319| Hashing criptografico | 45ms | 6ms | 7,5x |320~321WASM roda a aproximadamente 95% da velocidade do codigo nativo. Os maiores ganhos vem de:322- Desempenho previsivel (sem warmup JIT, sem pausas do GC)323- Instrucoes SIMD para processamento paralelo de dados324- Acesso direto a memoria sem interferencia do garbage collector325~326Onde o WASM NAO e mais rapido: manipulacao do DOM, calculos pequenos, tarefas limitadas por I/O. JavaScript ja esta otimizado para esses casos.327~328## Casos de uso em producao329~330### Figma: renderizacao vetorial em tempo real331~332O motor de renderizacao principal do Figma e C++ compilado para WASM. Cada forma, gradiente e efeito e calculado em WASM e desenhado em um elemento Canvas. Isso permite ao Figma lidar com designs complexos com milhares de camadas a 60fps no navegador - desempenho impossivel em JavaScript puro.333~334### Adobe Photoshop na web335~336A Adobe portou filtros e ferramentas chave do Photoshop para WASM usando Rust. Seus benchmarks mostram processamento de imagens 4K em 22ms com WASM SIMD contra 180ms em JavaScript - uma melhoria de 8 vezes que torna possiveis as previsualizacoes de filtros em tempo real.337~338### Cloudflare Workers339~340A Cloudflare executa modulos WASM em isolates V8 em mais de 330 localizacoes edge. Os cold starts sao de 1 a 5ms (comparados com 100 a 500ms do serverless baseado em conteineres). Em fevereiro de 2026, implantaram a inferencia do Llama-3-8b em sua rede edge usando WASM.341~342### Google Meet343~344O desfoque de fundo e os fundos virtuais no Google Meet usam WASM com SIMD para processamento de video em tempo real. O modulo WASM processa cada frame de video rapido o suficiente para manter um video fluido a 30fps.345~346## Suporte de navegadores (2026)347~348| Funcionalidade | Chrome | Firefox | Safari | Edge |349|----------------|--------|---------|--------|------|350| Core WASM | Completo | Completo | Completo | Completo |351| Threads | Sim | Sim | Sim | Sim |352| SIMD (128 bits) | Sim | Sim | Sim | Sim |353| WasmGC | 119+ | 120+ | 18.2+ | Sim |354| Exception Handling | Sim | Sim | Sim | Sim |355| Memory64 | Sim | Sim | Parcial | Sim |356~357Todos os navegadores principais suportam totalmente WASM. As funcionalidades mais recentes (WasmGC, Exception Handling) alcancaram ampla disponibilidade.358~359## Referencia de ferramentas360~361| Ferramenta | Proposito | Instalacao |362|------------|-----------|------------|363| **wasm-pack** | Compilar Rust para WASM, gerar pacotes npm | `cargo install wasm-pack` |364| **wasm-bindgen** | Bindings de interoperabilidade Rust/JS (usado pelo wasm-pack) | Dependencia no Cargo.toml |365| **wasm-opt** | Otimizacao do tamanho do binario (reducao de 50%+) | Parte do Binaryen: `brew install binaryen` |366| **wit-bindgen** | Gerar bindings a partir de arquivos WIT | `cargo install wit-bindgen-cli` |367| **Wasmtime** | Runtime WASM do lado do servidor (implementacao de referencia WASI) | `brew install wasmtime` |368| **Wasmer** | Runtime WASM alternativo com suporte WASI | `curl https://get.wasmer.io -sSfL \| sh` |369| **wasm-feature-detect** | Deteccao de funcionalidades do navegador em tempo de execucao | `npm install wasm-feature-detect` |370~371### Otimizar o tamanho do binario372~373Os binarios WASM podem ser grandes. Veja como reduzi-los:374~375```toml376# Cargo.toml377[profile.release]378opt-level = "z" # Optimize for size379lto = true # Link-time optimization380codegen-units = 1 # Better optimization, slower compile381strip = true # Strip debug symbols382```383~384```bash385# Build in release mode386wasm-pack build --release --target web387~388# Further optimize with wasm-opt389wasm-opt -Oz pkg/image_processor_bg.wasm -o pkg/image_processor_bg.wasm390```391~392Um modulo WASM tipico em Rust vai de 500KB para menos de 50KB com essas otimizacoes.393~394## Roteiro para comecar395~396```mermaid397flowchart TD398 A[Week 1: Basics] --> B[Week 2: Real Project]399 B --> C[Week 3: WASI and Server-side]400 C --> D[Month 2+: Production]401~402 A --> A1[Install Rust + wasm-pack]403 A --> A2[Build hello-world WASM module]404 A --> A3[Call WASM functions from JavaScript]405~406 B --> B1[Build image processor or game physics]407 B --> B2[Use wasm-bindgen for rich types]408 B --> B3[Benchmark against pure JS]409~410 C --> C1[Run WASM with Wasmtime]411 C --> C2[Explore WASI interfaces]412 C --> C3[Try Component Model with WIT]413~414 D --> D1[Optimize binary size]415 D --> D2[Use SIMD for parallelism]416 D --> D3[Deploy to Cloudflare Workers or browser]417```418~419## Conclusao420~421WebAssembly nao e mais experimental. E uma tecnologia de producao usada por algumas das aplicacoes mais exigentes da web. Desempenho quase nativo, seguranca em sandbox e portabilidade universal - nenhum outro alvo de compilacao oferece as tres coisas.422~423Voce nao precisa reescrever toda a sua aplicacao em WASM. Comece com uma unica funcao intensiva em CPU - um filtro de imagem, um parser de dados, um calculo fisico - compile para WASM e chame a partir do JavaScript. Meca a diferenca. Depois decida onde mais o WASM pode ajudar.424~425As ferramentas sao maduras, o suporte dos navegadores e universal e o ecossistema esta crescendo. Se voce escreve em Rust, ja esta a um comando de distancia do navegador.426~427> **Checklist para comecar:**428>429> - [x] Rust e wasm-pack instalados430> - [x] Primeiro modulo WASM compilado e funcionando no navegador431> - [x] Interoperabilidade com JavaScript funcionando (chamando WASM a partir do JS)432> - [x] Build de release com otimizacoes de tamanho aplicadas433> - [x] Desempenho comparado com o equivalente em JavaScript puro434> - [x] WASI explorado com Wasmtime para casos de uso do lado do servidor435~
NORMAL · webassembly-wasm-complete-guide.md [readonly]435 lines · :q to close