Skip to content

About

Reproducible browser-performance research and evidence for Proa

Resources

Stars

7 stars

Watchers

0 watching

Forks

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Proa benchmarks

Proa 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.

The SvelteKit comparison adds production HTTP, cold-start, product-scaling, and browser-complete streaming measurements. Native SvelteKit promise streaming sends data for the browser to render; its response end is a different boundary from Proa’s resolved-HTML stream.

If you see an issue with the benchmarks or would like to add any, please open an issue!

Rendering the same pages in seventeen renderers

Renderer-only benchmark across three canonical pages: component, table, and product grid.

Dot plot of seventeen renderers across three workloads, on a logarithmic axis of render time relative to Proa

Seventeen renderers, one-core P50 multiples on log scale. Details · Full size · how the figures are built

Serving three pages on one core

Three sample pages, one core each: throughput at saturation, latency at a fixed request rate.

Sustained responses per second, CPU per response, and peak RSS for Proa, React, Marko, Go html/template, and SvelteKit serving three canonical pages over HTTP on one core

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 core

Legacy one-core mechanism view: workload speed vs Proa memcpy floor.

Render time relative to memcpy across three workloads and eleven showcase pages on one core

Three workloads + allocation context as multiples of a memcpy baseline. Details · Full size · how the figures are built

Streaming the product grid through Suspense

Single-core Suspense streaming with eight async boundaries per request.

Overlaid HTTP streaming throughput and memory for Proa, Marko, React and SvelteKit, with four latency panels on a shared scale

Four engines on shared throughput, memory, and latency scales. Marko/React source · Proa/SvelteKit source. SvelteKit response end excludes browser rendering; see complete-DOM timings. Full size · how the figures are built

Canonical latency tails on one core

Single-core P50 and P95 for the same three canonical workloads.

P50 and P95 render-latency spread for seventeen renderers on three workloads, one core

Tail spread with heavy-tail markers on three workloads. Details · Full size · how the figures are built

Proa linked showcase corpus

Proa-only linked pages: five runs each, with render range and size.

Proa linked showcase corpus render times

Application-like page samples and stability notes. Details · Full size · how the figures are built

Cold start to first response

Startup latency from process creation to first byte-identical response.

Median, P95 and slowest time from process spawn to first complete product-grid response for Proa, React, Marko, Go html/template and SvelteKit, with RSS after the first response

Median, P95, and worst-start across 15 fresh processes. Details · Full size · how the figures are built

Reproducing a capture

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
npm ci --prefix rendering/external/svelte
npm ci --prefix rendering/external/sveltekit

Run timed suites sequentially. The runners build their servers, gate parity before timing, and reject a phase whose load generator was the bottleneck. The report commands regenerate the evidence pages and figures.

./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
node sveltekit/run.mjs         # Proa vs SvelteKit HTTP streaming + browser completion
node sveltekit/report.mjs      # regenerate SvelteKit comparison
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.

Next steps

License and attribution

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, SvelteKit, 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.

About

Reproducible browser-performance research and evidence for Proa

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages