js-framework-benchmark
Stefan Krause's long-running comparison of JavaScript UI frameworks on one fixed workload: build,
mutate and tear down a table of rows, in Chrome, under WebDriver, with the browser's own timeline
supplying the timings. 186 implementations are currently in it, split into keyed and non-keyed
variants, and each is a real implementation of the same specified app rather than a vendor's demo.
Read here from the published result set (webdriver-ts-results/src/results.ts), not the interactive
page, which renders its tables in the browser.
This is the source svelte said did not exist. That page has carried, since ingest, that
"nobody has measured a Svelte application against a React one on bundle size, update cost or anything
else." Somebody has, on every axis, for years, and this wiki had not looked. The claim is retracted
there.
The numbers, keyed implementations
Median of the published runs. Vanilla JavaScript is included because it is the floor — the same app with no framework at all.
| Svelte 5.42.1 | React 19.2.0 | Vue 3.5.39 | vanilla JS | |
|---|---|---|---|---|
| create 1,000 rows | 21.9 ms | 23.7 ms | 24.5 ms | 20.6 ms |
| replace all rows | 24.6 ms | 30.0 ms | 27.1 ms | 21.9 ms |
| partial update (every 10th) | 10.8 ms | 14.0 ms | 12.7 ms | 9.8 ms |
| select row | 4.8 ms | 5.5 ms | 3.7 ms | 2.5 ms |
| swap 2 rows | 12.6 ms | 89.9 ms | 13.4 ms | 10.9 ms |
| remove row | 10.2 ms | 11.1 ms | 12.2 ms | 9.7 ms |
| create 10,000 rows | 231.0 ms | 388.9 ms | 264.0 ms | 212.2 ms |
| append 1k to a 1k table | 25.1 ms | 29.2 ms | 27.6 ms | 23.5 ms |
| clear rows | 10.2 ms | 17.8 ms | 12.6 ms | 8.8 ms |
| memory after load | 0.66 MB | 1.19 MB | 0.87 MB | 0.57 MB |
| memory with 1k rows | 2.87 MB | 4.44 MB | 3.93 MB | 1.86 MB |
| transfer size, brotli | 9.7 KB | 51.4 KB | 23.3 KB | 2.5 KB |
| first paint | 58.4 ms | 221.4 ms | 93.9 ms | 52.7 ms |
Several of the update benchmarks run under a 2× or 4× CPU slowdown, which is stated per benchmark and is the same for every framework.
What it settles, and it is less than the marketing on either side
Compiling the framework away is worth about 5× in bytes, not 20×. Brotli-compressed, Svelte ships 9.7 KB against React's 51.4 KB for the identical application. Secondary write-ups of this comparison routinely quote "2–5 KB versus 42 KB" by weighing an empty framework import rather than a working app; the measured ratio on a real implementation is 5.3×, and vanilla JavaScript at 2.5 KB shows how much of Svelte's 9.7 KB is still framework.
On most operations the gap is small. Creating a thousand rows separates the four by under 4 ms. Removing a row separates them by under 2. A reader of svelte's and react's own documentation would expect the compile-first design to win everywhere; on this workload it wins narrowly and sometimes loses to Vue.
One operation is not small. Swap two rows costs React 89.9 ms against Svelte's 12.6, Vue's 13.4 and vanilla's 10.9 — a 7× outlier in a table where nothing else exceeds 1.7×. Swapping two rows in a keyed list is the case where a diffing reconciler has to establish that almost nothing changed, and the cost of proving that is what the number is. It is the clearest empirical instance of the mechanism split svelte and react describe from their own docs: knowing the dependency graph at build time beats rediscovering it per update, and the difference only shows up where rediscovery is expensive.
The React Compiler does not close it. react-compiler-hooks 19.0.0 measures 90.4 ms on the same
swap against plain hooks' 89.9, with every other row within noise. The compiler memoises components;
it does not remove the reconciler, so it cannot touch the cost that the reconciler is. Trade write-ups
claiming React 19's compiler "significantly narrows the performance gap" are not describing this
benchmark.
What it is not
A table is not an application. This measures DOM throughput under adversarial list mutation — no routing, no data fetching, no forms, no third-party components, no code splitting, and no team. The numbers say what each framework's update path costs when that path is the entire program, which is a real property and a narrow one. Nothing here supports a claim about how either framework behaves in a product, and the ecosystem, hiring and maintenance arguments this comparison is usually deployed in are untouched by it.
Two further limits. Each framework's entry is written by contributors who want it to do well, so implementation quality is a variable the benchmark does not control; Krause notes he cannot audit all 186. And the result set is a snapshot on one machine — read the ordering, not the milliseconds.
Related
svelte · react · ui-framework · flutter · design-system · synthesis
Cross-spoke. Transfer size and first paint are ../webperf-wiki's subject; this page keeps the
framework comparison and that spoke keeps the delivery budget. The measurement method — an independent
party running everyone's implementations on one harness — is the shape the hub's standing "nobody
re-runs anybody's numbers" item keeps looking for.