Saying goodbye to asm.js

Performance and Benchmarks

  • Some report asm.js SHA-256 implementations outperforming available WebAssembly (Wasm) libraries in browsers, with specific benchmarks showing:
    • In Chrome on Windows: asm.js ≈ 2× faster than Wasm for a given SHA-256 implementation.
    • In Firefox: Wasm ≈ 2× faster than asm.js (with asm optimizations) and ≈ 2× faster than Chrome’s Wasm for that benchmark.
  • Others argue that in modern Firefox, asm.js is compiled through the same pipeline as Wasm, so asm.js cannot be intrinsically faster; better or worse codegen and engine differences likely explain gaps.
  • Several commenters stress that “X is faster than Y” is highly context-dependent (browser, platform, module, workload).

WebCrypto and Hashing Use Cases

  • crypto.subtle.digest is praised for speed but:
    • Requires a secure origin.
    • Is async-only.
    • Lacks incremental hashing, making it unsuitable for very large files without full buffering.
  • These gaps motivate custom asm.js/Wasm hashing solutions.

Wasm vs asm.js: Capabilities and Integration

  • Wasm benefits mentioned:
    • Access to SIMD, bulk memory ops, GC types, externref, evolving proposals (memory control, stack switching).
    • Fewer bounds checks and better memory strategies.
  • Criticisms / limitations raised:
    • Isolation from JS and web APIs; most web APIs still require JS “shim” calls.
    • No direct zero-copy sharing of arbitrary ArrayBuffers; extra copies needed when moving data into Wasm heaps.
  • Clarifications:
    • Strict asm.js also cannot directly call most web APIs or avoid copies; it is closer to Wasm-with-JS-syntax than to general JS.
    • Some think asm.js “can do everything JS can do,” others correct that it’s numerically constrained and cannot handle JS objects/strings directly.

Runtime Code Generation and Tooling

  • Concern: losing asm.js optimizations hurts dynamic codegen patterns.
  • Others note:
    • asm.js remains valid JS; it just won’t get a special fast path.
    • Generating Wasm at runtime is described as straightforward with small helper libraries or encoders in Rust/JS.
  • Legacy pain points:
    • Emscripten dropped asm.js support; compiling old asm.js-targeting code with old toolchains is frustrating.
    • Desire for an asm.js → Wasm transpiler; an older asm2wasm tool existed in Binaryen but is now deprecated.

NaCl/PNaCl and Historical Trajectory

  • Thread revisits NaCl (native machine code sandbox) and PNaCl (LLVM bitcode) as predecessors/alternatives:
    • PNaCl suffered from heavy startup costs and non-standard APIs tied to Chrome.
    • Wasm is seen as a cleaner, CPU-agnostic, multi-implementation standard.
  • Some lament an “alternate timeline” where NaCl/PNaCl or a more mature Wasm replaced today’s heavier Electron-style apps.

Ecosystem Maturity and Pain Points

  • Reported shortcomings of current Wasm ecosystem (especially in browsers):
    • No direct DOM/web-API access without JS glue.
    • Multithreading via Web Workers is cumbersome and header-dependent (COOP/COEP).
    • No zero-copy streaming interfaces; data marshalling overhead with WebGPU and others.
    • Fragmented runtimes and a messy WASI story; async and threading are awkward.
  • Others respond that Wasm is evolving slowly but deliberately (e.g., GC, stack switching, interior pointer discussions, components/WASI work).

Real-World Apps and Sentiment

  • asm.js credited with enabling early “thick” web apps and demos (e.g., large C++ codebases, Unreal Engine in browser, design tools).
  • Some see its removal as technically sensible but emotionally nostalgic; others view it as just retiring an obsolete compilation target.
  • Mixed feelings about everything moving into the browser: some praise distribution and collaboration benefits; others wish more for native/desktop options.