Skip to content

Performance

Petar Liovic edited this page Sep 9, 2026 · 1 revision

Dev-only cost. Production wrappers are no-ops.

Numbers below are from the example app and synthetic ranker runs (Feb 2026). Your app will differ.

Recording

Each instrumented variable has a fixed Uint8Array ring. A write overwrites one slot. Filtered heap comparisons show no new Uint8Array constructors between snapshots:

Uint8Array filter empty Uint8Array filter empty, second pair

The graph is a sparse Map of edges. Virtual event nodes older than the interaction window are dropped so a long session does not keep every click forever.

A full-heap comparison over a long run can still grow for other reasons (React, DevTools, PerformanceMeasure). This snapshot went 59 MB → 114 MB; almost all of the delta is PerformanceMeasure, not rings:

heap comparison

Treat that as “rings are stable,” not “the tab’s heap never moves.”

When work runs

  • Sampling: requestAnimationFrame (one bit per frame).
  • Pairwise work: requestIdleCallback, and only for variables that wrote since the last pass.
  • Ranking / full report: when you ask for it (printBasisReport), not every frame.

Report cost (synthetic)

benchmarkRanker(), 100 runs:

Graph Average per report
18 nodes ~0.31 ms
~30k nodes ~27 ms
18 node ranker 30k node ranker

30k nodes is a torture graph, not a typical UI. Still on-demand.

Interaction

Burst in the example app, Chrome local metrics: INP 48 ms (pointer on button.secondary). That is inside Chrome’s “good” band for this recording. It is not a promise about every app.

INP 48ms

Per-frame bookkeeping in that kind of burst was in the low tenths of a millisecond when we looked. Re-measure if you change the engine.

Clone this wiki locally