Unified Vue Lynx benchmark matrix

IFR × VDOM/Vapor × ReactLynx on one scale. Conclusions up top (easy to digest); tables and charts below for verification. Median latency; (n.nn) = slowdown vs the row’s best. Generated 2026-07-28 · git 346eccf · 4× Intel(R) Xeon(R) Processor @ 2.80GHz.

env: lynx-web (primary) ladder: 1k → 30k cells: 764 conclusions: 8 Engine cells: N/A on this host (no engine ET PAPI on Lynx for Web) — omitted from all tables and charts

中文

Conclusions

Title = takeaway; so what = how to use; verify = numbers. Never ratio ms across environments.

Vapor ~8.3× on point updates

so what Select = point update. Default Vapor for interaction-heavy lists; one-shots often sit on the frame floor.

verify selectStorm@10k 984→119 ms · vs RL ~22× · BG ~9.8×

ReactLynx wins create ~1.05×

so what Snapshot bulk-instantiate. Creation ≠ update.

verify create@10k RL 1659 · VDOM 1736 · Vapor 1732 ms

ReactLynx lowest FCP

so what Same-density probe: RL wins. Vue first-frame → vdom +b +ifr.

verify FCP@10k RL 241 · +b +ifr 373 · vdom baseline 452 ms

No +ifr without +b

so what “−19%” isn’t a constant. vdom +ifr (no +b) loses at scale; default vdom +b +ifr.

verify vs off: 1k -21% · 10k +33%

+b speeds updates ~2%

so what Template clone helps post-mount too. +ifr (no +b) ≈ baseline.

verify selectStorm@10k baseline 984 · +ifr 995 · +b +ifr 968 ms

Vapor sparse naming ×1 FCP -20%

so what Keeper sparse A2 helps ×1 on this host; ×4 is not a hedge. Native ET remains the big lever.

verify dense 152.9 → sparse 121.8 ms · ×4 +12%

create→RL · updates→Vapor · Vue FCP→vdom +b +ifr

so what Select=point, Update=batch. Product choice collapses to this line.

verify See tables below; never divide ms across instruments.

Quote ratios, not ms

so what Medians move 2×+ across hosts. Same-host ratios only.

verify Ex: older host React selectStorm@10k ≈2544 ms; this host ≈2632 ms.

Table storms — IFR × framework matrix

Black-box: real clicks → composed-DOM end state. Single-host full sweep (all four-axis permutations + ReactLynx × 1k/10k/30k in one run; per-key newest single-host samples win). Select = point update (selection / a few classes per tick); Update = batch update (many rows touched each pass). ReactLynx (memo) = Snapshot + IFR (always on) + manual memo/useCallback.

scenariovdom (baseline)vdom +bvdom +ifrvdom +b +ifrvapor (baseline)vapor +b (default)vapor +b! (bundle delivery)vapor +b:c (code staging)vapor +ifrvapor +b +ifr (default +ifr)rl (Snapshot+IFR+memo)
create · 1k rows202.3 ms(1.13)201.9 ms(1.13)199.7 ms(1.12)217.0 ms(1.21)190.8 ms(1.07)213.5 ms(1.19)201.2 ms(1.12)196.8 ms(1.10)210.3 ms(1.18)201.9 ms(1.13)178.9 ms(1.00)
update storm ×50 · 1k127.4 ms(2.06)126.1 ms(2.04)124.6 ms(2.02)132.6 ms(2.15)66.5 ms(1.08)67.4 ms(1.09)66.4 ms(1.08)61.7 ms(1.00)68.3 ms(1.11)68.8 ms(1.12)579.0 ms(9.38)
select storm ×30 · 1k70.9 ms(5.37)64.6 ms(4.89)67.5 ms(5.12)65.1 ms(4.94)19.5 ms(1.48)20.5 ms(1.56)20.1 ms(1.52)13.2 ms(1.00)13.8 ms(1.05)19.2 ms(1.45)225.5 ms(17.08)
create · 10k rows1.74 s(1.09)1.60 s(1.00)1.66 s(1.04)1.68 s(1.05)1.65 s(1.03)1.73 s(1.08)1.77 s(1.11)1.76 s(1.10)1.65 s(1.03)1.73 s(1.08)1.66 s(1.04)
update every 10th · 10k114.8 ms(1.31)115.4 ms(1.32)117.1 ms(1.34)117.2 ms(1.34)91.6 ms(1.05)88.8 ms(1.02)87.4 ms(1.00)95.1 ms(1.09)89.6 ms(1.03)95.3 ms(1.09)265.3 ms(3.04)
select row · 10k79.5 ms(1.64)77.7 ms(1.61)81.7 ms(1.69)81.1 ms(1.68)57.8 ms(1.20)66.7 ms(1.38)72.9 ms(1.51)57.7 ms(1.19)48.4 ms(1.00)56.9 ms(1.18)155.2 ms(3.21)
update storm ×50 · 10k1.86 s(2.66)1.94 s(2.78)1.97 s(2.82)1.89 s(2.71)729.8 ms(1.04)887.6 ms(1.27)918.2 ms(1.31)759.7 ms(1.09)699.6 ms(1.00)740.5 ms(1.06)6.04 s(8.64)
select storm ×30 · 10k984.1 ms(10.59)1.04 s(11.19)994.6 ms(10.70)967.9 ms(10.41)106.0 ms(1.14)118.6 ms(1.28)106.8 ms(1.15)115.7 ms(1.24)92.9 ms(1.00)124.7 ms(1.34)2.63 s(28.32)
create · 30k rows5.28 s(1.13)4.85 s(1.04)4.83 s(1.04)5.40 s(1.16)5.13 s(1.10)5.36 s(1.15)5.05 s(1.08)5.04 s(1.08)5.13 s(1.10)5.18 s(1.11)4.66 s(1.00)
update storm ×50 · 30k10.9 s(1.79)7.21 s(1.18)7.34 s(1.20)7.51 s(1.23)6.74 s(1.10)7.22 s(1.18)6.11 s(1.00)7.29 s(1.19)6.33 s(1.03)7.07 s(1.16)21.2 s(3.46)
select storm ×30 · 30k3.57 s(12.97)3.23 s(11.73)3.33 s(12.10)3.17 s(11.53)306.1 ms(1.11)275.2 ms(1.00)332.6 ms(1.21)309.7 ms(1.13)322.3 ms(1.17)362.9 ms(1.32)10.3 s(37.29)
slowdown geometric mean2.482.322.352.381.121.191.181.111.061.185.02
≤ 1.15× ≤ 2.5× ≤ 10× > 10×

Storm scaling (1k → 30k)

Linear axes, zero baseline — absolute gaps, not log-compressed shape. Select charts = point updates; Update charts = batch throughput.

select storm (point) vs table size

Point updates: wall time for 30 sequential selects — each tick touches selection state only. The vapor family stays flat; ReactLynx climbs; vdom +b +ifr pulls vdom down.

drag a box to zoom · wheel to scale · double-click to reset · hover to highlight
05k10k15k20k25k30k0ms2s4s6s8s10srl (Snapshot+IFR+memo)vdom (baseline)vdom +ifrvdom +bvdom +b +ifrvapor +b +ifr (default +ifr)vapor +b! (bundle delivery)vapor +ifrvapor +b:c (code staging)vapor (baseline)vapor +b (default) rows N — linear select storm — ms

update storm (batch) vs table size

Batch updates: wall time for 50 multi-row update passes. Creation is separate — sustained batch throughput only.

drag a box to zoom · wheel to scale · double-click to reset · hover to highlight
05k10k15k20k25k30k0ms5s10s15s20srl (Snapshot+IFR+memo)vdom (baseline)vdom +b +ifrvdom +ifrvapor +b:c (code staging)vapor +b (default)vdom +bvapor +b +ifr (default +ifr)vapor (baseline)vapor +ifrvapor +b! (bundle delivery) rows N — linear update storm — ms

create vs table size

ReactLynx still leads creation. vdom +b +ifr slightly helps create via template clone.

drag a box to zoom · wheel to scale · double-click to reset · hover to highlight
05k10k15k20k25k30k0ms1s2s3s4s5svdom +b +ifrvapor +b (default)vdom (baseline)vapor +b +ifr (default +ifr)vapor +ifrvapor (baseline)vapor +b! (bundle delivery)vapor +b:c (code staging)vdom +bvdom +ifrrl (Snapshot+IFR+memo) rows N — linear create — ms

Select storm — log scale (all)

On a linear axis the Vapor family is pinned to the floor; a log axis separates all three orders of magnitude.

drag a box to zoom · wheel to scale · double-click to reset · hover to highlight
05k10k15k20k25k30k10ms100ms1s10s100srl (Snapshot+IFR+memo)vdom (baseline)vdom +ifrvdom +bvdom +b +ifrvapor +b +ifr (default +ifr)vapor +b! (bundle delivery)vapor +ifrvapor +b:c (code staging)vapor (baseline)vapor +b (default) rows N — linear select storm — ms

Select storm — Vapor family (zoom)

Vapor variants only, own y-scale — resolves baseline / +b / +ifr / +b +ifr from each other (V4 notation).

drag a box to zoom · wheel to scale · double-click to reset · hover to highlight
05k10k15k20k25k30k0ms100ms200ms300msvapor +b +ifr (default +ifr)vapor +b! (bundle delivery)vapor +ifrvapor +b:c (code staging)vapor (baseline)vapor +b (default) rows N — linear select storm — ms

Content-probe FCP (architecture ladder)

Same card density (~1k→30k els): every four-axis permutation + ReactLynx Snapshot+IFR, one single-host sweep (sfc-probe scale ladder). This is the first-frame scale — not comparable to storm ms above. Table below: CPU ×1; every cell covers 1k→30k (×4 covers through 10k).

scalevdom (baseline)vdom +bvdom +ifrvdom +b +ifrvapor (baseline)vapor +b (default)vapor +b! (bundle delivery)vapor +b:c (code staging)vapor +ifrvapor +b +ifr (default +ifr)vapor +b +ifr:crl
1k elements128.3 ms(1.73)114.3 ms(1.54)101.6 ms(1.37)98.1 ms(1.33)160.6 ms(2.17)173.6 ms(2.35)163.6 ms(2.21)168.8 ms(2.28)152.9 ms(2.07)144.8 ms(1.96)157.2 ms(2.12)74.0 ms(1.00)
3k elements204.9 ms(1.86)212.5 ms(1.93)177.4 ms(1.61)160.8 ms(1.46)255.2 ms(2.32)268.8 ms(2.45)312.5 ms(2.84)290.5 ms(2.64)235.7 ms(2.14)232.8 ms(2.12)260.4 ms(2.37)109.9 ms(1.00)
5k elements258.5 ms(1.70)258.4 ms(1.70)252.1 ms(1.65)221.0 ms(1.45)378.7 ms(2.48)379.5 ms(2.49)388.3 ms(2.55)411.8 ms(2.70)345.1 ms(2.26)345.6 ms(2.27)347.0 ms(2.28)152.4 ms(1.00)
10k elements452.1 ms(1.87)472.8 ms(1.96)601.6 ms(2.49)372.8 ms(1.54)644.0 ms(2.67)626.4 ms(2.60)727.8 ms(3.02)712.6 ms(2.95)583.1 ms(2.42)576.7 ms(2.39)624.2 ms(2.59)241.3 ms(1.00)
20k elements839.0 ms(1.83)829.1 ms(1.81)1.05 s(2.29)708.2 ms(1.55)1.21 s(2.65)1.15 s(2.52)1.26 s(2.76)1.33 s(2.90)1.11 s(2.42)1.06 s(2.30)1.16 s(2.52)458.0 ms(1.00)
30k elements1.17 s(1.67)1.21 s(1.72)1.51 s(2.16)1.59 s(2.26)1.80 s(2.56)1.73 s(2.47)1.78 s(2.53)2.02 s(2.88)1.54 s(2.19)1.66 s(2.36)1.60 s(2.28)702.2 ms(1.00)

CPU ×4 (same matrix; ladder clipped to 10k — full ×4 coverage only through 10k).

scalevdom (baseline)vdom +bvdom +ifrvdom +b +ifrvapor (baseline)vapor +b (default)vapor +b! (bundle delivery)vapor +b:c (code staging)vapor +ifrvapor +b +ifr (default +ifr)vapor +b +ifr:crl
1k elements582.3 ms(1.26)510.6 ms(1.10)649.4 ms(1.41)516.3 ms(1.12)503.4 ms(1.09)498.2 ms(1.08)547.3 ms(1.18)501.6 ms(1.09)596.0 ms(1.29)564.4 ms(1.22)530.6 ms(1.15)462.2 ms(1.00)
3k elements1.22 s(1.60)1.01 s(1.32)1.13 s(1.47)926.8 ms(1.21)923.9 ms(1.20)837.9 ms(1.09)973.9 ms(1.27)944.6 ms(1.23)1.07 s(1.40)1.04 s(1.36)1.14 s(1.49)766.9 ms(1.00)
5k elements1.62 s(1.39)1.42 s(1.22)1.51 s(1.30)1.33 s(1.15)1.42 s(1.22)1.26 s(1.08)1.27 s(1.09)1.35 s(1.16)1.55 s(1.33)1.49 s(1.28)1.58 s(1.35)1.17 s(1.00)
10k elements2.90 s(1.47)2.47 s(1.25)3.24 s(1.64)2.36 s(1.20)2.52 s(1.27)2.42 s(1.22)2.29 s(1.16)2.32 s(1.18)2.63 s(1.33)2.56 s(1.29)2.76 s(1.39)1.98 s(1.00)

FCP vs content scale (CPU ×1)

ReactLynx lowest throughout. Among Vue: vdom +ifr (no +b) crosses above vdom baseline by 10k; vdom +b +ifr is the scale hedge.

drag a box to zoom · wheel to scale · double-click to reset · hover to highlight
05k10k15k20k25k30k0ms500ms1s1.5s2svapor +b:c (code staging)vapor (baseline)vapor +b! (bundle delivery)vapor +b (default)vapor +b +ifr (default +ifr)vapor +b +ifr:cvdom +b +ifrvapor +ifrvdom +ifrvdom +bvdom (baseline)rl elements N — linear FCP — ms

FCP vs content scale (CPU ×4, through 10k)

Ladder clipped to 10k (full ×4 coverage). Slow CPU amplifies MT parse cost.

drag a box to zoom · wheel to scale · double-click to reset · hover to highlight
02k4k6k8k10k0ms1s2s3svdom +ifrvdom (baseline)vapor +b +ifr:cvapor +ifrvapor +b +ifr (default +ifr)vapor (baseline)vdom +bvapor +b (default)vdom +b +ifrvapor +b:c (code staging)vapor +b! (bundle delivery)rl elements N — linear FCP — ms

Graph-eng naming unit — node (Named Tree) vs block (Tree-Template)

Same-source sfc-probe (~1004 els): only enableSparseNaming flips. Native ET still stub; sparse still builds the full native tree. See ifr-bench/GRAPH-ENG-MATRIX.md.

scenarionamingweb gzipFCP ×1ΔFCP ×4Δ
vapor +ifr vapor-ifr-densedense89,720152.9 ms+0.0%596.0 ms+0.0%
vapor +b +ifr (alias) vapor-ifr-sparsesparse90,007121.8 ms-20.3%670.2 ms+12.4%
vapor +b +ifr (default +ifr) vapor-ifrsparse90,007144.8 ms-5.3%564.4 ms-5.3%

Optimization-flag matrix — all-permutation create/update + factor attribution

Unified table app (real clicks, dual-thread), every legal optimization combination (cell name = baseline × +b[:t|c|e] × +ifr[:c|e], see the legend below; a factor = per-flag marginal Δ%), each measured for create / update10th / updateStorm / select / selectStorm (1k/10k, reps=2 — read ±10% as noise). Factors = single-axis marginal Δ%. Engine cells are recorded as N/A on this host (Lynx for Web has no engine ET PAPI) and filtered out of the tables by default (toggle at the top reveals them); their interpretation-fallback control samples remain in the results JSON. See ifr-bench/GRAPH-ENG-REPORT.md §3.3.

Flag legend (cell name = baseline × stacked flags, matching factor attribution one-to-one)

flagmeaning
baselineper-node addressing — plainest and safest: every node named independently, no metadata, no validation. vdom = op stream; vapor = named tree.
+bblock templates: use the template block's parts information for block naming (base+offset) and template materialization. The staging parameter defaults to the render model's natural rung — vdom +b+b:c (code: baked create()); vapor +b+b:d (data: the serialized tree crosses the thread boundary as data at RUNTIME — REGISTER_TREE once per template — interpreted on the MT; forced by the Split topology). The two +b factors are therefore not comparable across render models. The information source differs too: intrinsic for vdom (declared by Vue's Block), recovered for vapor (compile-time analysis, hence the fingerprint fail-safe).
+b:cvapor staging raised to the code rung (#337): the plugin parses each template() HTML string at build time, bakes a straight-line-PAPI create() into the MT bundle, and instantiation crosses as a single INSTANTIATE_TEMPLATE(id) — the residual never crosses at runtime. Naming keeps the base+offset preorder, the update path is untouched; a build↔runtime structure-fingerprint mismatch silently falls back to the REGISTER_TREE data path.
+b!the Delivery column flipped alone (#338): staging stays data, but the serialized tree is baked into the MT bundle at BUILD time (registerVaporStructure(hash, ast)); the BG sends only the fingerprint hash (REGISTER_TREE_BUNDLE) — zero structure bytes cross. Interpretation, naming, and the update path are byte-identical to vapor +b; on hash mismatch it silently falls back to the full REGISTER_TREE.
+b:estaging raised to the engine rung: templates live in the engine (__CreateElementTemplate family), native clone. Applies to the persistent tree. N/A on this host (Lynx for Web has no such PAPI).
delivery(sixth property column) when the residual reaches the MT: runtime = shipped over the wire (vapor +b's data today, and native); bundle = compiled into the MT bundle at build (vdom's code, RL Snapshot, vapor's +b! and +b:c). +b! is the one cell that flips Delivery with every other column held fixed — the pure single-column delivery read.
+ifrIFR: the MTS paints an ephemeral first-frame copy; on BG boot, hydration adopts it or replays in full. The paint parameter defaults to inheriting the persistent tree's staging.
+ifr:eONLY the first-frame copy is painted at the engine rung (legacy name engine-et); the persistent tree is unchanged. Distinct from +b:e (whole lifetime). N/A on this host.
+ifr:cONLY the first-frame copy is painted at the code rung (#340): the ephemeral frame runs a Code-Template create() executor compiled at RUNTIME on the MT, while the persistent tree stays data/block (legacy name disposable-et). Distinct from +b:c (whole lifetime, baked at build). Unlike +ifr:e this is measured on this host (no longer N/A) — see the +ifr:c paint effect row and its takeaway card.

Data files keep legacy keys (mapping: vdom-et=vdom +b, vapor=vapor +b (default), vapor-dense=vapor baseline, vapor-bang=vapor +b!, vapor-code=vapor +b:c, vapor-ifr-dense=vapor +ifr, vapor-engine=+b:e, vapor-ifr-engine-et=+ifr:e, vapor-ifr-code-paint=+ifr:c). vapor-ifr-sparse is a same-coordinate replicate of vapor +b +ifr, omitted from display (data retained in JSON). Mechanism terms (Named Tree / Tree-Template / Code-Template / Engine-Template) and the five-axis coordinates live in GRAPH-ENG-REPORT.md.

scenario @1kcoordinatecreateupdate10thupdateStormselectselectStorm
vdom vdomops/node/random-access/BTS/persistent/—202.3 ms24.7 ms127.4 ms26.6 ms70.9 ms
vdom +b vdom-etcode/block/random-access/BTS/persistent/bundle201.9 ms24.8 ms126.1 ms26.1 ms64.6 ms
vdom +ifr vdom-ifrops/node/random-access/BTS+MTS/persistent+ephemeral/—199.7 ms23.2 ms124.6 ms26.5 ms67.5 ms
vdom +b +ifr vdom-ifr-etcode/block/random-access/BTS+MTS/persistent+ephemeral/bundle217.0 ms26.9 ms132.6 ms26.0 ms65.1 ms
vapor vapor-densedata/node/traversal/BTS/persistent/runtime190.8 ms26.3 ms66.5 ms27.0 ms19.5 ms
vapor +b vapordata/block/traversal+recover/BTS/persistent/runtime213.5 ms26.9 ms67.4 ms27.0 ms20.5 ms
vapor +b! vapor-bangdata/block/traversal+recover/BTS/persistent/bundle201.2 ms24.5 ms66.4 ms26.1 ms20.1 ms
vapor +b:c vapor-codecode/block/traversal+recover/BTS/persistent/bundle196.8 ms25.5 ms61.7 ms27.1 ms13.2 ms
vapor +ifr vapor-ifr-densedata/node/traversal/BTS+MTS/persistent+ephemeral/runtime210.3 ms21.3 ms68.3 ms25.8 ms13.8 ms
vapor +b +ifr vapor-ifrdata/block/traversal+recover/BTS+MTS/persistent+ephemeral/runtime201.9 ms27.0 ms68.8 ms17.0 ms19.2 ms
scenario @10kcoordinatecreateupdate10thupdateStormselectselectStorm
vdom vdomops/node/random-access/BTS/persistent/—1.74 s114.8 ms1.86 s79.5 ms984.1 ms
vdom +b vdom-etcode/block/random-access/BTS/persistent/bundle1.60 s115.4 ms1.94 s77.7 ms1.04 s
vdom +ifr vdom-ifrops/node/random-access/BTS+MTS/persistent+ephemeral/—1.66 s117.1 ms1.97 s81.7 ms994.6 ms
vdom +b +ifr vdom-ifr-etcode/block/random-access/BTS+MTS/persistent+ephemeral/bundle1.68 s117.2 ms1.89 s81.1 ms967.9 ms
vapor vapor-densedata/node/traversal/BTS/persistent/runtime1.65 s91.6 ms729.8 ms57.8 ms106.0 ms
vapor +b vapordata/block/traversal+recover/BTS/persistent/runtime1.73 s88.8 ms887.6 ms66.7 ms118.6 ms
vapor +b! vapor-bangdata/block/traversal+recover/BTS/persistent/bundle1.77 s87.4 ms918.2 ms72.9 ms106.8 ms
vapor +b:c vapor-codecode/block/traversal+recover/BTS/persistent/bundle1.76 s95.1 ms759.7 ms57.7 ms115.7 ms
vapor +ifr vapor-ifr-densedata/node/traversal/BTS+MTS/persistent+ephemeral/runtime1.65 s89.6 ms699.6 ms48.4 ms92.9 ms
vapor +b +ifr vapor-ifrdata/block/traversal+recover/BTS+MTS/persistent+ephemeral/runtime1.73 s95.3 ms740.5 ms56.9 ms124.7 ms
scenario @30kcoordinatecreateupdate10thupdateStormselectselectStorm
vdom vdomops/node/random-access/BTS/persistent/—5.28 s478.3 ms10.9 s308.4 ms3.57 s
vdom +b vdom-etcode/block/random-access/BTS/persistent/bundle4.85 s355.9 ms7.21 s248.6 ms3.23 s
vdom +ifr vdom-ifrops/node/random-access/BTS+MTS/persistent+ephemeral/—4.83 s370.0 ms7.34 s306.8 ms3.33 s
vdom +b +ifr vdom-ifr-etcode/block/random-access/BTS+MTS/persistent+ephemeral/bundle5.40 s369.9 ms7.51 s242.3 ms3.17 s
vapor vapor-densedata/node/traversal/BTS/persistent/runtime5.13 s253.8 ms6.74 s268.7 ms306.1 ms
vapor +b vapordata/block/traversal+recover/BTS/persistent/runtime5.36 s266.2 ms7.22 s236.8 ms275.2 ms
vapor +b! vapor-bangdata/block/traversal+recover/BTS/persistent/bundle5.05 s250.4 ms6.11 s275.4 ms332.6 ms
vapor +b:c vapor-codecode/block/traversal+recover/BTS/persistent/bundle5.04 s257.2 ms7.29 s291.3 ms309.7 ms
vapor +ifr vapor-ifr-densedata/node/traversal/BTS+MTS/persistent+ephemeral/runtime5.13 s242.9 ms6.33 s272.1 ms322.3 ms
vapor +b +ifr vapor-ifrdata/block/traversal+recover/BTS+MTS/persistent+ephemeral/runtime5.18 s250.6 ms7.07 s288.9 ms362.9 ms

Main effects (one flag flipped at a time). Each flag co-moves several coordinate axes (see the “flag ↔ coordinate axis” map below), so these numbers attribute to flag granularity and cannot be split finer. Charts: bars left (negative) = the flag makes that op faster; read ±10% as noise (reps=2). Engine factors are stub probe overhead on web.

Main effects @1k (Δ% — left/negative = faster)

create update10th updateStorm select selectStorm
-73%+73%0render effect (vdom → vapor, baselines)-5.7%+6.5%-47.8%+1.5%-72.5%+b effect (vdom, no ifr)-0.2%+0.4%-1%-1.9%-8.9%+b effect (vdom, with +ifr)+8.7%+15.9%+6.4%-1.9%-3.6%+b effect (vapor, no ifr)+11.9%+2.3%+1.4%0%+5.1%+b effect (vapor, with +ifr)-4%+26.8%+0.7%-34.1%+39.1%+b! delivery effect (vapor)-5.8%-8.9%-1.5%-3.3%-2%+b:d→c effect (vapor)-7.8%-5.2%-8.5%+0.4%-35.6%+ifr effect (vdom)-1.3%-6.1%-2.2%-0.4%-4.8%+ifr effect (vapor +b)-5.4%+0.4%+2.1%-37%-6.3%

Main effects @10k (Δ% — left/negative = faster)

create update10th updateStorm select selectStorm
-89%+89%0render effect (vdom → vapor, baselines)-5.2%-20.2%-60.7%-27.3%-89.2%+b effect (vdom, no ifr)-7.9%+0.5%+4.5%-2.3%+5.7%+b effect (vdom, with +ifr)+1.3%+0.1%-3.9%-0.7%-2.7%+b effect (vapor, no ifr)+5.3%-3.1%+21.6%+15.4%+11.9%+b effect (vapor, with +ifr)+4.5%+6.4%+5.8%+17.6%+34.2%+b! delivery effect (vapor)+2.1%-1.6%+3.4%+9.3%-9.9%+b:d→c effect (vapor)+1.5%+7.1%-14.4%-13.5%-2.4%+ifr effect (vdom)-4.3%+2%+6.1%+2.8%+1.1%+ifr effect (vapor +b)-0.3%+7.3%-16.6%-14.7%+5.1%

Main effects @30k (Δ% — left/negative = faster)

create update10th updateStorm select selectStorm
-91%+91%0render effect (vdom → vapor, baselines)-2.8%-46.9%-38.4%-12.9%-91.4%+b effect (vdom, no ifr)-8.1%-25.6%-34.1%-19.4%-9.6%+b effect (vdom, with +ifr)+11.7%0%+2.4%-21%-4.7%+b effect (vapor, no ifr)+4.5%+4.9%+7.2%-11.9%-10.1%+b effect (vapor, with +ifr)+0.9%+3.2%+11.8%+6.2%+12.6%+b! delivery effect (vapor)-5.8%-5.9%-15.3%+16.3%+20.9%+b:d→c effect (vapor)-6%-3.4%+1%+23%+12.5%+ifr effect (vdom)-8.4%-22.6%-32.9%-0.5%-6.7%+ifr effect (vapor +b)-3.4%-5.9%-2.1%+22%+31.9%

Main-effect takeaways

Update and select are template-blind.Both +b factor rows (vdom and vapor) sit inside the ±10% noise band on update10th / select / updateStorm / selectStorm at every scale — corroborating the ops-level factorial (identical update frames + native calls in every cell). Templates change who builds the first frame, not how holes are written.
Template create benefit shows up only on static-heavy screens.Negative = faster. The table app's create is dominated by dynamic v-for rows and templating only covers the small static skeleton, so the staging factor on create is -0.2%…-8.1% ≈ noise; on static-heavy content (the sfc-probe FCP ladder) block/code templates are the one factor negative (faster) at every scale. Rule: measure your first screen's static fraction before reaching for templates.
The render axis (vdom→vapor) is the update lever: updateStorm -47.8% / -60.7% / -38.4% (1k→30k) — far beyond any template axis. Pick the render model for interaction performance; don't expect templates to move it.
IFR is a first-frame lever, not an interaction lever: the ifr factor is significant only on create/FCP, its update factors sit in noise; under ×4 vapor's IFR first-frame cost is recovered by +b (baseline +12% → +b +2%).
So what does vapor +b actually do?On the dynamic table it barely moves create / update / select / storm latency (inside the ±10% noise band at every scale). Its two real, measured payoffs are: (1) memory / bookkeeping — −94% BG shells, −92% MT table entries (exact counts); and (2) static-heavy first frame — block staging makes first-frame construction cheaper, the benefit scaling with the subtree's static fraction. In one line: +b is a memory + static-first-frame optimization, not a dynamic-latency lever. The work we spent on +b / +ifr buys those two things, not table interaction latency.
+b:e and +ifr:e are N/A on this host(Lynx for Web has no engine ET PAPI; __VUE_LYNX_ENGINE_ET_STATUS__ = stub). Their interpretation-fallback control samples serve only as a fail-safe-cost / noise yardstick, never as engine conclusions; the axis runs end-to-end and reports real numbers the day the engine PAPI ships.
+b! (delivery flipped alone, #338) and +b:c (code staging, #337) are now measured — the benefit is CONDITIONAL on small-template × many-instances, not universal.Storms table app (small row template × tens of thousands of instances): +b! create -5.8% / +2.1% / -5.8%, +b:c create -7.8% / +1.5% / -6% (1k/10k/30k); update/select factors sit inside the reps=2 noise envelope (the interpretation-identical +b:e stub row swings the same ±20% at 30k — template-blindness confirmed again). Structure bytes cross zero by construction (the table app's registration wire drops 1165 B → 99 B fingerprint frames; +b:c sends no registration at all — wire-bytes counters embedded in the factor JSON). The content first-screen probe (one mega static template × ONE instance) points the OTHER way: at ×1 both cells get SLOWER with scale (up to ~+16% FCP) — the bundle-resident residual is parsed on the MT boot critical path; at 30k the MT section grows from 8 kB gzip to 14 kB (+b!) / 487 kB (+b:c) (raw 24 kB → 1.1 MB / 3.5 MB). The prior guess band (+b:c create −5…−17% by static fraction) came from the vdom ET precedent of many small per-card create()s and does NOT transfer to vapor's single-mega-template shape; +b!'s structure-wire −100% holds byte-for-byte. Eligibility rule: bake only when the residual is small and instantiated many times (list rows); a single-instance mega-template belongs on the data path — gate by template size. Both cells' update paths are byte-identical to vapor +b (fingerprint fail-safe + mutated-hash test underneath).
+ifr:c (code-paint, #340) is a wash on the first frame.Painting the ephemeral IFR copy through a runtime-compiled Code-Template create() executor (durable tree stays data/block) moves content-probe FCP vs plain vapor +b +ifr by ×1 -3.3%…+11.9%, ×4 -6%…+9.5%, mean +5.2% — see the +ifr:c paint effect row. The mechanism matches the +b:c storms verdict: a single ephemeral instantiation is dominated by PAPI element creation (identical in both paints); the code rung only removes the per-node interpreter walk, a small fraction of first-frame cost. Unlike +ifr:e this is a real measurement — the Code-Template executor runs on web.

flag ↔ coordinate-axis map (which axes each flag co-moves)

flagstagingnamingaccessthreadlifetimeoriginaxes moved
renderops→data·random-access→traversal··—→runtime3
+b (vdom)ops→codenode→block···—→bundle3
+b (vapor)·node→blocktraversal→traversal+recover···2
+ifr···BTS→BTS+MTSpersistent→persistent+ephemeral·2
+b:e (N/A on web)data→native··BTS→Engine··2
+ifr:e (N/A on web)·····runtime→runtime(native-paint)1

Each row is one cell→cell move; the lit columns are the axes that flag co-moves, diffed straight from the 6-slot coord string (not invented). Because these axes are collinear+ifr always moves thread and lifetime together, render moves 3 at once — the Δ% in the factor tables attributes only to flag granularity and cannot be split into per-axis numbers. The native/engine axes are N/A on this host (a fail-safe-cost yardstick only).

factor (marginal Δ%) @1kcreateupdate10thupdateStormselectselectStorm
render effect (vdom → vapor, baselines)-5.7%+6.5%-47.8%+1.5%-72.5%
+b effect (vdom, no ifr)-0.2%+0.4%-1%-1.9%-8.9%
+b effect (vdom, with +ifr)+8.7%+15.9%+6.4%-1.9%-3.6%
+b effect (vapor, no ifr)+11.9%+2.3%+1.4%+0%+5.1%
+b effect (vapor, with +ifr)-4%+26.8%+0.7%-34.1%+39.1%
+b! delivery effect (vapor)-5.8%-8.9%-1.5%-3.3%-2%
+b:d→c effect (vapor)-7.8%-5.2%-8.5%+0.4%-35.6%
+ifr effect (vdom)-1.3%-6.1%-2.2%-0.4%-4.8%
+ifr effect (vapor +b)-5.4%+0.4%+2.1%-37%-6.3%
factor (marginal Δ%) @10kcreateupdate10thupdateStormselectselectStorm
render effect (vdom → vapor, baselines)-5.2%-20.2%-60.7%-27.3%-89.2%
+b effect (vdom, no ifr)-7.9%+0.5%+4.5%-2.3%+5.7%
+b effect (vdom, with +ifr)+1.3%+0.1%-3.9%-0.7%-2.7%
+b effect (vapor, no ifr)+5.3%-3.1%+21.6%+15.4%+11.9%
+b effect (vapor, with +ifr)+4.5%+6.4%+5.8%+17.6%+34.2%
+b! delivery effect (vapor)+2.1%-1.6%+3.4%+9.3%-9.9%
+b:d→c effect (vapor)+1.5%+7.1%-14.4%-13.5%-2.4%
+ifr effect (vdom)-4.3%+2%+6.1%+2.8%+1.1%
+ifr effect (vapor +b)-0.3%+7.3%-16.6%-14.7%+5.1%
factor (marginal Δ%) @30kcreateupdate10thupdateStormselectselectStorm
render effect (vdom → vapor, baselines)-2.8%-46.9%-38.4%-12.9%-91.4%
+b effect (vdom, no ifr)-8.1%-25.6%-34.1%-19.4%-9.6%
+b effect (vdom, with +ifr)+11.7%+0%+2.4%-21%-4.7%
+b effect (vapor, no ifr)+4.5%+4.9%+7.2%-11.9%-10.1%
+b effect (vapor, with +ifr)+0.9%+3.2%+11.8%+6.2%+12.6%
+b! delivery effect (vapor)-5.8%-5.9%-15.3%+16.3%+20.9%
+b:d→c effect (vapor)-6%-3.4%+1%+23%+12.5%
+ifr effect (vdom)-8.4%-22.6%-32.9%-0.5%-6.7%
+ifr effect (vapor +b)-3.4%-5.9%-2.1%+22%+31.9%

FCP main effects (content-probe first-frame scale — a different instrument from the storm ms above; do not ratio across):

FCP main effects ×1 (Δ% — left/negative = faster first frame)

@1k @3k @5k @10k @20k @30k
-54%+54%render effect (vdom → vapor, baselines)+b effect (vdom, no ifr)+b effect (vdom, with +ifr)+b effect (vapor, no ifr)+b effect (vapor, with +ifr)+b! delivery effect (vapor)+b:d→c effect (vapor)+b:d→e effect (vapor, N/A)+ifr effect (vdom)+ifr effect (vapor +b)+ifr:e paint effect (N/A)+ifr:c paint effect

FCP main effects ×4 (Δ% — left/negative = faster first frame)

@1k @3k @5k @10k
-44%+44%render effect (vdom → vapor, baselines)+b effect (vdom, no ifr)+b effect (vdom, with +ifr)+b effect (vapor, no ifr)+b effect (vapor, with +ifr)+b! delivery effect (vapor)+b:d→c effect (vapor)+b:d→e effect (vapor, N/A)+ifr effect (vdom)+ifr effect (vapor +b)+ifr:e paint effect (N/A)+ifr:c paint effect
factor (FCP Δ%)×1 @1k×1 @3k×1 @5k×1 @10k×1 @20k×1 @30k×4 @1k×4 @3k×4 @5k×4 @10k
render effect (vdom → vapor, baselines)+25.2%+24.5%+46.5%+42.4%+44.5%+53.8%-13.5%-24.5%-12.1%-13.2%
+b effect (vdom, no ifr)-10.9%+3.7%0%+4.6%-1.2%+3%-12.3%-17.1%-12.1%-15%
+b effect (vdom, with +ifr)-3.4%-9.4%-12.3%-38%-32.6%+4.9%-20.5%-17.9%-11.8%-27.1%
+b effect (vapor, no ifr)+8.1%+5.3%+0.2%-2.7%-4.9%-3.7%-1%-9.3%-11.4%-4.1%
+b effect (vapor, with +ifr)-5.3%-1.2%+0.1%-1.1%-4.8%+7.5%-5.3%-2.3%-3.6%-2.6%
+b! delivery effect (vapor)-5.8%+16.3%+2.3%+16.2%+9.6%+2.3%+9.9%+16.2%+0.7%-5.2%
+b:d→c effect (vapor)-2.8%+8.1%+8.5%+13.8%+15.1%+16.6%+0.7%+12.7%+7.3%-3.8%
+b:d→e effect (vapor, N/A)-14.6%-13.2%-16.6%-12.8%-13.3%-13.4%+22.6%+44.4%+33.7%+23.2%
+ifr effect (vdom)-20.8%-13.4%-2.5%+33.1%+25.2%+29.4%+11.5%-7.7%-6.4%+11.7%
+ifr effect (vapor +b)-16.6%-13.4%-8.9%-7.9%-8.4%-4.5%+13.3%+24.7%+18.5%+6%
+ifr:e paint effect (N/A)-9.1%-13.2%-19.7%-14.3%-14.1%-22.5%+16.2%+26.4%+28.6%+33.1%
+ifr:c paint effect+8.6%+11.9%+0.4%+8.2%+9.6%-3.3%-6%+9.5%+5.7%+7.7%

Coverage

What each architecture has been measured for in the unified schema.

architecturetable stormscontent-probe FCPinstrumented BG/e2e
vdom (baseline) vdom
vdom +ifr vdom-ifr
vdom +b +ifr vdom-ifr-et
vapor +b (default) vapor
vapor +b +ifr (default +ifr) vapor-ifr
vapor +ifr vapor-ifr-dense
vdom +b vdom-et
vapor (baseline) vapor-dense
vapor +b:c (code staging) vapor-code
vapor +b! (bundle delivery) vapor-bang
vapor +b +ifr:c vapor-ifr-code-paint
rl (Snapshot+IFR+memo) react
ReactLynx (naive) react-naive
ReactLynx (compiler) react-compiler