Reproducible browser-performance research and evidence for Proa
See the codeProa renders typed Rust components to HTML on the server, streams them, and hydrates fine-grained browser islands. This page shows what one core serves over HTTP, how fast seventeen renderers render those pages, and how to reproduce them.
If you see an issue with the benchmarks or would like to add any, please open an issue!
Rendering the same pages in seventeen renderersRenderer-only benchmark across three canonical pages: component, table, and product grid. Seventeen renderers, one-core P50 multiples on log scale. Details · Full size · how the figures are built | |
Serving three pages on one coreThree sample pages, one core each: throughput at saturation, latency at a fixed request rate. Three parity-gated pages on loopback HTTP, one core per engine. Details · Full size · how the figures are built |
Render time vs memcpy on one coreLegacy one-core mechanism view: workload speed vs Proa memcpy floor. Three workloads + allocation context as multiples of a memcpy baseline. Details · Full size · how the figures are built |
Streaming the product grid through SuspenseSingle-core Suspense streaming with eight async boundaries per request. Throughput sweep with queueing markers (P50/P95/P99 + memory) at each rate. Details · Full size · how the figures are built |
Canonical latency tails on one coreSingle-core P50 and P95 for the same three canonical workloads. Tail spread with heavy-tail markers on three workloads. Details · Full size · how the figures are built |
Proa linked showcase corpusProa-only linked pages: five runs each, with render range and size. Application-like page samples and stability notes. Details · Full size · how the figures are built |
Cold start to first responseStartup latency from process creation to first byte-identical response. Median, P95, and worst-start across 15 fresh processes. Details · Full size · how the figures are built |
Install the JavaScript dependencies once. You need Node.js 24.20.0 exactly — the canonical runner compares process.version and refuses to run on anything else — with pnpm, the Rust toolchain in rust-toolchain.toml, and Go 1.25. The full scoreboard also needs Ruby 3.2+, a JDK 17+ with Gradle, PHP 8, and Python 3.13+.
pnpm install --frozen-lockfile
pnpm exec playwright install chromium
npm ci --prefix rendering/external/react
npm ci --prefix rendering/external/marko
npm ci --prefix rendering/external/handlebars
Then run a suite. Each command builds its servers, gates every page for parity, and rewrites its evidence page. It refuses to publish a phase whose load generator was the bottleneck.
./rendering/run-all # scoreboard: build, parity-gate, time, regenerate scoreboard.md
pnpm run bench:page-load # canonical pages over HTTP, one core each
pnpm run bench:cold-start # cold start to first response
pnpm run bench:suspense-load # Suspense streaming over HTTP
pnpm run refresh # regenerate every evidence page and figure from the captures
Good to know: the committed numbers are dated evidence from one machine, not universal claims. Rerun the relevant suite before publishing a current comparison.
rendering/, page-load/, suspense-load/, load/, showcase/, agent-chain/, and the separate travel-agent/ control.This repository is Apache-2.0; see LICENSE. Benchmark adapters incorporate upstream work under its own terms, recorded in rendering/UPSTREAM_LICENSES.md.
React, Marko, Vue, Svelte, Rails, jte, Rocker, Handlebars, Go, Jinja2, PHP, Askama, Sailfish, Leptos, Dioxus, and Topcoat belong to their respective owners. They appear here as the subjects of a benchmark; their inclusion implies no endorsement.
Reproducible browser-performance research and evidence for Proa
See the codeProa renders typed Rust components to HTML on the server, streams them, and hydrates fine-grained browser islands. This page shows what one core serves over HTTP, how fast seventeen renderers render those pages, and how to reproduce them.
If you see an issue with the benchmarks or would like to add any, please open an issue!
Rendering the same pages in seventeen renderersRenderer-only benchmark across three canonical pages: component, table, and product grid. Seventeen renderers, one-core P50 multiples on log scale. Details · Full size · how the figures are built | |
Serving three pages on one coreThree sample pages, one core each: throughput at saturation, latency at a fixed request rate. Three parity-gated pages on loopback HTTP, one core per engine. Details · Full size · how the figures are built |
Render time vs memcpy on one coreLegacy one-core mechanism view: workload speed vs Proa memcpy floor. Three workloads + allocation context as multiples of a memcpy baseline. Details · Full size · how the figures are built |
Streaming the product grid through SuspenseSingle-core Suspense streaming with eight async boundaries per request. Throughput sweep with queueing markers (P50/P95/P99 + memory) at each rate. Details · Full size · how the figures are built |
Canonical latency tails on one coreSingle-core P50 and P95 for the same three canonical workloads. Tail spread with heavy-tail markers on three workloads. Details · Full size · how the figures are built |
Proa linked showcase corpusProa-only linked pages: five runs each, with render range and size. Application-like page samples and stability notes. Details · Full size · how the figures are built |
Cold start to first responseStartup latency from process creation to first byte-identical response. Median, P95, and worst-start across 15 fresh processes. Details · Full size · how the figures are built |
Install the JavaScript dependencies once. You need Node.js 24.20.0 exactly — the canonical runner compares process.version and refuses to run on anything else — with pnpm, the Rust toolchain in rust-toolchain.toml, and Go 1.25. The full scoreboard also needs Ruby 3.2+, a JDK 17+ with Gradle, PHP 8, and Python 3.13+.
pnpm install --frozen-lockfile
pnpm exec playwright install chromium
npm ci --prefix rendering/external/react
npm ci --prefix rendering/external/marko
npm ci --prefix rendering/external/handlebars
Then run a suite. Each command builds its servers, gates every page for parity, and rewrites its evidence page. It refuses to publish a phase whose load generator was the bottleneck.
./rendering/run-all # scoreboard: build, parity-gate, time, regenerate scoreboard.md
pnpm run bench:page-load # canonical pages over HTTP, one core each
pnpm run bench:cold-start # cold start to first response
pnpm run bench:suspense-load # Suspense streaming over HTTP
pnpm run refresh # regenerate every evidence page and figure from the captures
Good to know: the committed numbers are dated evidence from one machine, not universal claims. Rerun the relevant suite before publishing a current comparison.
rendering/, page-load/, suspense-load/, load/, showcase/, agent-chain/, and the separate travel-agent/ control.This repository is Apache-2.0; see LICENSE. Benchmark adapters incorporate upstream work under its own terms, recorded in rendering/UPSTREAM_LICENSES.md.
React, Marko, Vue, Svelte, Rails, jte, Rocker, Handlebars, Go, Jinja2, PHP, Askama, Sailfish, Leptos, Dioxus, and Topcoat belong to their respective owners. They appear here as the subjects of a benchmark; their inclusion implies no endorsement.