Skip to content

Performance

Results from js-framework-benchmark, the benchmark most JavaScript frameworks publish against. It builds a table of rows and measures the time, the memory and the bundle size of a set of operations on it.

Fable.Ripple 1.0.0-beta.1 (Fable.Ripple and Fable.Ripple.Dom) is measured against the hand-written DOM implementation, two fine-grained compilers and a virtual DOM. Every entry is the keyed variant.

Run in Chrome on Linux. Each operation is the median of 15 measured runs after warmup, 25 for select a row. Memory and size are measured once. Lower is better everywhere.

The benchmark throttles the CPU on the operations that are otherwise too short to time, marked in the table below. Every framework is throttled the same way, so the ratios hold; the milliseconds in those rows are not comparable with the unthrottled ones.

Absolute numbers depend on the machine. The ratio against vanillajs, the hand-written implementation, is the figure to compare.

Summary

Geometric mean of each group's ratios to vanillajs. 1.00 is the hand-written implementation.

GroupvanillajsSolid 1.9.3Svelte 5.42.1Fable.RippleReact 19.2.0
Operations1.001.101.141.171.67
Memory1.001.221.401.432.47
Size and startup1.001.242.223.0710.55

Operations

Time in milliseconds.

BenchmarkvanillajsSolid 1.9.3Svelte 5.42.1Fable.RippleReact 19.2.0
create 1,000 rows42.744.144.751.350.0
replace all 1,000 rows45.548.949.056.457.7
update every 10th row, 16 cycles (4x CPU)18.019.519.818.523.7
select a row (4x CPU)3.74.76.84.97.4
swap two rows (4x CPU)22.023.924.523.8179.6
remove a row (2x CPU)19.719.920.019.521.2
create 10,000 rows434.5453.4458.1516.5617.5
append 1,000 rows to 1,000, 2 cycles46.148.448.955.054.9
clear 1,000 rows, 8 cycles (4x CPU)15.920.118.120.528.2

Updating every 10th row, swapping and removing are within 10% of the hand-written implementation: each writes the nodes that changed and nothing else. Creating rows is 20% behind, at 1,000 rows and at 10,000.

Memory

Heap size in MB.

BenchmarkvanillajsSolid 1.9.3Svelte 5.42.1Fable.RippleReact 19.2.0
after load0.570.600.670.691.19
after creating 1,000 rows1.872.692.872.974.42
after creating and clearing 1,000 rows, 5 cycles0.650.770.980.981.97

In this implementation a row holds one Var for its label and two reactive bindings, which is what the hand-written version does not allocate. The last row is measured after the table has been emptied, so it shows what a framework holds on to.

Size and startup

Size of the implementation files, excluding CSS and HTTP headers.

BenchmarkvanillajsSolid 1.9.3Svelte 5.42.1Fable.RippleReact 19.2.0
Uncompressed (kB)11.311.526.642.8190.3
Brotli (kB)2.54.59.712.951.4
First paint (ms)74.777.789.5110.3253.6

12.9 kB brotli is the application plus Fable.Ripple, Fable.Ripple.Dom and the part of the Fable JavaScript library it uses. Solid and Svelte compile their templates away; Fable.Ripple ships its DSL as runtime code.

Edit this page