Skip to content

Performance Lab

Chris Michael edited this page Jul 25, 2026 · 6 revisions

Effuse

Performance Lab

Effuse performance claims must be backed by reproducible production-build measurements. The repository performance lab owns benchmark scenarios, machine-readable reports, and conservative regression budgets.

Commands

pnpm bench:routes
pnpm bench:routes:bun

Both commands build the production core package, verify its browser entry, warm each route operation, collect 30 timing batches, and enforce median and p95 guardrails.

The route suite currently measures pattern parsing, compilation, matching, resolution, specificity comparison, and a realistic route-table scan. Pass --json directly to scripts/performance/route-pattern.mjs for schema-versioned output containing units, sample configuration, runtime version, platform, and architecture.

Interpretation

  • Median represents the typical sampled batch.
  • p95 exposes slower batches that a median can hide.
  • Standard deviation and range indicate measurement stability.
  • Versioned budgets catch large Effuse regressions across variable CI hardware.
  • Budgets are not proof that Effuse is faster than another framework.

Cross-framework comparisons must use equivalent features, payloads, production builds, runtimes, warmup, sample counts, and hardware constraints. Results must publish losses and unmeasured areas alongside wins.

Landed Optimizations

Change Measured effect
Radix-trie route index (#330) server.router-match 1585 ns → 966 ns. Worst-case lookup is flat in route count: at 1000 routes 46900 ns → 270 ns (173x).
Guarded SSR escaping (#332) Escape helpers 3.3–9.6x faster on clean input, break-even on input that needs escaping. A 50 KB, 200-row document render improved ~997 µs → ~570 µs (1.7x).
Allocation-free render loop (#334) Direct switch dispatch (no per-node closure object), hoisted void-element Set, and index-loop child concatenation. Same document ~570 µs → ~410 µs (1.4x), for ~2.4x cumulative versus the pre-optimization baseline.
Deferred-head streaming (#336) Shell flushes with pre-render static head before the body renders. Time-to-first-chunk is now flat regardless of document size (was 93% of drain and scaling with the body): at 800 rows (~98 KB) TTFC dropped ~880 µs → ~314 µs.
Precompiled middleware patterns (#301) Selection rebuilt a regex per middleware per request. Compiling patterns once at graph compile time moved matched dispatch from 80692 ns to 8209 ns (9.8x), trading a one-time boot cost.

These are guarded by scenarios in this lab: route.trie-match, route.trie-match-large, ssr.render-document, middleware.compile-graph, and middleware.select-chain. The middleware benchmarks found the regex bug above on their first run, which is the argument for adding a benchmark before assuming a path is fast.

Two implementation notes worth keeping, because both contradict intuition:

  • A manual charCodeAt escape loop regressed long clean strings by 15x. V8's native regex scan beats a JavaScript loop for the no-match case, so the fast path uses a native character-class test.
  • A single replace with a callback map is slower than chained literal replaces, because V8 specialises replace(regex, literalString) and a callback adds per-match JavaScript overhead.

Roadmap

#249 tracks cold start, server-handler throughput, SSR latency, hydration and mount cost, update latency, memory, client bytes, CI baselines, and reviewed competitor fixtures.

Routing and SSR render slices have landed. Broader framework superiority is a goal to prove, not a status claim.

Measurement Matrix

Performance work is scoped by what the framework actually controls. Mixing framework cost with deployment cost produces claims that cannot be defended.

Owned by Effuse — measurable in this repository:

  • Routing and middleware dispatch (landed)
  • SSR document render and escaping (landed)
  • Streaming: time to first chunk (landed — constant TTFC via deferred-head streaming) and inter-chunk latency
  • Hydration cost and time to interactive
  • Client bundle size and code-splitting effectiveness
  • Server memory and CPU per render, and behaviour under concurrency
  • Suspense boundary and loading-state overhead
  • Server-side data fetching primitives: loader and route-handler overhead
  • Framework-level caching: compiled registries, route and policy caches

Application-owned — Effuse can only avoid adding overhead:

  • Database and upstream API latency
  • Client data-fetching library behaviour
  • Third-party script impact
  • Image and font strategy

Deployment-owned — out of scope for framework benchmarks:

  • CDN and edge-versus-regional latency, edge cache hit rate
  • Compression, HTTP/2 and HTTP/3, Cache-Control headers

Composite field metrics — Core Web Vitals (LCP, INP, CLS), TTFB, FCP, TTI, TBT, and Speed Index — are outcomes of all three layers. They belong in a fixture application measured under stated conditions, not in a microbenchmark suite, and must never be attributed to the framework alone.

Clone this wiki locally