fusor / benchmarks

PERFORMANCE LAB

Measure first.
Make the tradeoffs visible.

The same work, six frameworks. Production builds, checked output, and the raw numbers behind every result.

Recorded samples · warmups timing resultsDownload raw JSON ↓

This run contains failed checks. Missing results are shown as —; inspect the raw report before drawing conclusions.

Swipe the table to compare all six frameworks →

Production benchmark results. Lower times and bundle sizes are better. Values below the timer resolution are shown as less than 0.10 milliseconds.
Workload Lower is betterfusor React Svelte SolidJS Vue Preact
Lowest measured time in the row. Near-zero timings are limited by the browser clock. Bundle columns include HTML + JavaScript + Wasm.

ALLOCATION & CLEANUP

Memory needs its own context.

Chromium · forced GC

JavaScript heap and WebAssembly linear memory are different accounting domains. These figures are diagnostic measurements, not a whole-process RAM ranking.

Memory diagnostics in mebibytes. Heap values are changes from the same application's warmed, empty baseline.
Framework10k rowsJS heap Δ · MiB100k rowsJS heap Δ · MiBAfter 10 cyclesJS heap Δ · MiBWasm capacityMiB · not live bytesDOM nodesΔ after cleanup

Heap and node deltas use a warmed, empty application; retained runtime caches are already included in that baseline. A Wasm allocator can reuse freed memory without shrinking its linear memory. Retained capacity alone is not evidence of a leak. Ten mount/unmount cycles can find regressions; they cannot prove that every application is leak-free.

BROWSERChromium
MACHINE
SYSTEM
ARTIFACTS raw bytes inspected

READ THE FINE PRINT

A benchmark is a workload, not a verdict.

Full methodology ↗
01

Equivalent outcomes

Every timed operation is followed by output checks. Keyed tests verify order and surviving node identity. Hydration must retain server rows and bind each handler once.

02

Explicit timing boundaries

DOM tests end at the framework's commit barrier. They exclude layout and paint. Startup is navigation to interactive rows on localhost, with a fresh browser context.

03

Representations differ

React and Preact aggregate arrays for fan-in; signal frameworks track individual values. These measure equivalent application work, not identical reactive graph internals.

Run it on your machine.

The published run uses Binaryen 132. Install it and the prerequisites in the full methodology, then keep the raw samples. Omit FUSOR_WASM_OPT to measure the default compiler pipeline.

npm ci
npm ci --prefix benchmarks
export FUSOR_WASM_OPT=wasm-opt
just bench-build
BENCH_SEED=20261004 just bench-run my-run
# Review before publishing:
just bench publish --id my-run

The repository contains the harness and all six implementations under benchmarks/. There is no composite score. Browser scheduling, compiler versions, machine load, and application design all affect these results.