Skip to main content

Main-thread budget (worker → WASM, each step measured)

Generated from pattern-library/registry.json — do not edit by hand; change the registry and run bun run patterns:build.

Category: Runtime Velocity · Tier: deep · Maturity: proven (verified 2026-09-09 @ 921e8266-dirty) · Risk: medium — a worker boundary is a serialization contract

Expensive browser work moves off the main thread only where measurement justifies it: cheap stays inline, noticeable CPU work goes to a Web Worker, and WASM is reached for last — benchmarked against a line-for-line JS implementation including transfer cost.

When to use: Use for large parsing, image processing, graph layout, data crunching or expensive editor operations — anything that would otherwise block input and rendering.

Requires: web-worker

Avoid when

  • The operation is cheap or unmeasured — it stays on the main thread until a number justifies a worker
  • Serializing and transferring the payload costs about as much as the compute the worker would save
  • The work is server-side or scheduled — that is a background job, not a Web Worker

Alternatives

  • reduce the data or work before moving it — prefer when the input can be shrunk, sampled or paged so the operation stops blocking on its own
  • keep it inline on the main thread — prefer when measurement shows the operation does not noticeably block input or rendering
  • a Web Worker running plain JavaScript, without WASM — prefer when a WASM kernel has not beaten a line-for-line JS implementation with transfer cost included

Docs

Code

  • src/lib/workers/ — Image analysis off the main thread (GitHub · GitLab)
  • src/lib/wasm/ — Vendored Rust kernel, loaded via ?url with explicit init (GitHub · GitLab)

Tests

  • src/lib/wasm/kernel-parity.test.ts — The WASM and JS implementations must agree before either is benchmarked (GitHub · GitLab)

Proof

Invariants

  • Heavy compute does not unnecessarily block user input.
  • Worker and WASM boundaries are justified by measurement, not by expectation.
  • Serialization and transfer costs are inside the benchmark — without them a WASM comparison measures two different problems.
  • Parity between the fast implementation and the reference one is proven before speed is claimed.

Emulation notes

  • Pin the worker output format explicitly (worker.format: 'es'); a dev/prod format difference is a trap that only appears in the production build.
  • Vendor WASM artifacts rather than building them at install time: the toolchain is a much larger dependency than the output, and the build can run in an ephemeral container instead.

Machine-readable record: main-thread-budget in pattern-library/registry.json.

← Back to Pattern Library

Think this pattern could be better? Tell us how.

Leave feedback