demo · v137

C-loop unblocker

Two synthetic Wasm modules port an old C library that calls a network function in a loop. The left lane uses the legacy synchronous shim and freezes the page. The right lane uses JSPI to suspend the loop while the host await-s — the UI keeps ticking.

Origin trialJSPI ships in Chrome 137 stable. The demo uses a JS shim that models the same call shape so the comparison runs everywhere; the JSPI lane uses the real WebAssembly.Suspending API where available.
probing…
legacy: synchronous loop in Wasm

blocks the main thread

awaiting…

RAF pulse

v137: JSPI-suspended loop

cooperative, page stays interactive

awaiting…

RAF pulse

the code (JSPI lane)

// Old C: int fetch_one() { return blocking_fetch(); }
// We make blocking_fetch suspend the Wasm stack instead of blocking it.
const realFetch = async (url) => (await fetch(url)).status;
const importObj = {
  env: {
    blocking_fetch: new WebAssembly.Suspending(realFetch),
  },
};
const { instance } = await WebAssembly.instantiateStreaming(fetch("loop.wasm"), importObj);
const promising = WebAssembly.promising(instance.exports.run);
await promising(); // returns when the Wasm loop is done — UI never freezes

see also