Quando o servidor manda o .wasm com o MIME errado
O compileStreaming exige application/wasm. Um try/catch de quatro linhas salva o app em hospedagem que não sabe disso.
![]()
- O projeto tá aberto: github.com/joaomarcostg/compacta-pdf
O jeito recomendado de carregar WebAssembly é o WebAssembly.compileStreaming. Ele começa a compilar enquanto o arquivo ainda está baixando, em vez de esperar o download inteiro. Com um .wasm de 15 MB, como o do Ghostscript no Compacta PDF, isso é tempo que o usuário sente.
Só que ele tem uma exigência: a resposta precisa vir com Content-Type: application/wasm. Se o servidor mandar application/octet-stream ou outra coisa, o navegador recusa e a promise rejeita com um TypeError.
Isso acontece mais do que parece. Servidor de desenvolvimento antigo, hospedagem estática mal configurada, CDN corporativa. O app é estático justamente pra subir em qualquer lugar, então não dá pra confiar que todo lugar acerta o MIME.
A saída é tentar o caminho rápido e cair pro lento se der errado:
const res = await fetch(WASM_URL);
if (!res.ok) throw new Error(`Falha ao baixar (${res.status})`);
try {
return await WebAssembly.compileStreaming(res.clone());
} catch {
// MIME errado: compila a partir dos bytes
return WebAssembly.compile(await res.arrayBuffer());
}
O detalhe que faz isso funcionar é o res.clone(). O corpo de uma Response só pode ser lido uma vez. Se você passa a res original pro compileStreaming e ele falha, o corpo já foi consumido, e o arrayBuffer() do fallback quebra. Clonando, o streaming lê a cópia e o original fica intacto pro plano B.
Nada disso substitui configurar o servidor direito. Mas é a diferença entre “funciona na maioria dos lugares” e “funciona onde você subir”.