Skip to content

Commit 710df68

Browse files
SisyphusZhengDevBot
andauthored
test(v0.44): record Alpha.10 performance admission review (#1225) (#1267)
Co-authored-by: DevBot <devbot@openelement.dev>
1 parent 17ec6a5 commit 710df68

1 file changed

Lines changed: 209 additions & 0 deletions

File tree

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# Alpha.10 performance admission review (issue #1225)
2+
3+
This is the bounded structural-regression adjudication required by issue #1225
4+
(B1.6, stage #1150, umbrella #1155, authority ADR-0151). It reviews the
5+
Alpha.10 diagnostic benchmark baseline established by A10.11 / #1219 for
6+
structural contradictions with the architecture only. It is an adjudication
7+
record, not a ranking claim and not a performance SLO. Rank optimization and
8+
performance tuning are explicit non-goals of #1225.
9+
10+
## Reviewed baseline
11+
12+
- JFB browser baseline: `benchmarks/jfb/evidence.json` (schemaVersion 1,
13+
recordedAt 2026-09-02T17:34:29Z)
14+
- Kernel/Region/claim/compiler microbenchmarks:
15+
`benchmarks/v044/micro-evidence.json` (recordedAt 2026-09-02T17:31:52Z)
16+
- alpha.7 qualification matrix: `benchmarks/v044/evidence.json`
17+
- Narrative record: `docs/current/v0.44.0-PERFORMANCE.md`
18+
- Harness self-review: `benchmarks/jfb/README.md`
19+
20+
Baseline provenance: OpenElement SHA
21+
`493548a6b30b5f2912550c8dfaac70a8b9ef153f`; JFB commit
22+
`21d7204da754846fe1402f4437b5b53066f3c34e` with per-file SHA-256-pinned stock
23+
comparators (vanillajs, preact-signals, lit, solid, vue, svelte) built
24+
unmodified; Chromium 147.0.7727.15 via Playwright 1.59.1; stock afterframe
25+
timing and stock warmup counts; 10 CPU iterations per benchmark (stock 15,
26+
recorded deviation); Apple M2, 8 cores, 16 GB, macOS arm64; Deno 2.9.0, Node
27+
v24.18.0. Every number cited below was re-extracted from the committed
28+
evidence JSONs during this review and matches the narrative record.
29+
30+
## Evidence-SHA gap re-confirmation (carried risk, re-confirmed not re-litigated)
31+
32+
The benchmark evidence SHA `493548a6` predates this review's base SHA
33+
`17ec6a57`. Re-confirmed at `17ec6a57`:
34+
35+
- `git diff --stat 493548a6..17ec6a57 -- packages/element/src
36+
packages/adapter-vite/src packages/app/src packages/ui/src
37+
packages/create/src` → empty (zero product-source changes).
38+
- The intervening commits (#1259 baseline itself, #1261 docs truth, #1262
39+
docs/examples/www vocabulary, #1263 closure evidence and verifier tests,
40+
#1264/#1265 governance docs, #1266 package-surface freeze gate and docs)
41+
touch documentation, governance, examples, gates and tests only.
42+
43+
The measured semantics at `493548a6` are therefore the semantics at
44+
`17ec6a57`; the gap is docs/harness-only, as the Alpha.10 verifier already
45+
verified.
46+
47+
## Reproducibility spot-check at the review SHA
48+
49+
- `deno test -A benchmarks/` at `17ec6a57` → exit 0, 12 passed, 0 failed.
50+
These are the deterministic harness self-checks (`benchmarks/jfb/harness.test.ts`,
51+
`benchmarks/v044/micro.test.ts`, `benchmarks/v044/performance.test.ts`) that
52+
assert exact DOM-op counts, evidence schema and the frozen alpha budgets —
53+
never timings. The harness is intact; no harness fix was needed.
54+
55+
A full JFB browser re-run was not repeated: it rebuilds pinned stock
56+
comparators out-of-tree and would rewrite the committed evidence file, which
57+
this packet does not own. The deterministic count assertions plus the
58+
committed raw samples carry the reproducibility contract.
59+
60+
## Verdicts
61+
62+
Verdict scale per #1225: CLEAR (no structural regression, numbers cited) /
63+
ACCEPTED TRADE-OFF (documented with evidence) / BLOCKER (structural
64+
regression; stop and report).
65+
66+
### 1. Exact Part update catastrophically slower than comparable fine-grained systems — CLEAR
67+
68+
Browser (JFB `03_update10th`, partial update of every 10th row in 1k, median
69+
ms): OE 15.55 vs vanillajs 19.35, lit 23.95, solid 18.35, svelte 24.95 —
70+
OE is faster than four of six comparators including vanilla; preact-signals
71+
10.5 and vue 11.6 are faster than OE. No catastrophic gap in either
72+
direction.
73+
74+
Micro (fake DOM, exact op counts from `micro-evidence.json`):
75+
76+
- partial update of every 10th of 1k rows: exactly 100 text writes, 0
77+
allocations, 0 listener adds, 1.573 ms — one write per affected row, no
78+
more;
79+
- signal → text part: 0.448 µs/op, exactly 2000/2000 text writes;
80+
- signal → attr part: 0.265 µs/op, 2000/2000 attr writes;
81+
- signal → prop part: 1.309 µs/op, 1999/2000 value writes (equality guard,
82+
explained);
83+
- engine floor (signal write, no part): 0.096 µs/op.
84+
85+
Per-update Part overhead over the raw signal-write floor is 0.17–1.2 µs and
86+
is fully explained by the op counts: the exact Part update path writes only
87+
the affected Part. No structural regression.
88+
89+
### 2. Keyed Region pathological complexity — ACCEPTED TRADE-OFF
90+
91+
The one outlier in the baseline: keyed `swap1k` performs 997 node moves
92+
(insertions) for a 2-row swap — the Region move is O(distance)
93+
node-by-node. Browser median 19.85 ms vs solid 7.85, preact-signals 9.55,
94+
vanillajs 12.8; but vue 19.7, lit 21.25 and svelte 22.7 are equal or worse.
95+
96+
Why this is a trade-off, not a blocker:
97+
98+
- The complexity is linear in move distance, not superlinear; there is no
99+
unbounded or quadratic path anywhere in the Region evidence.
100+
- Every other keyed Region op is mid-pack or better (median ms): replace1k
101+
27.35 (lit 282.6), remove1k 11.15 (lit 21.95, svelte 22.5), clear1k 4.15
102+
(lit 330, preact-signals 12.5), append1k 41.95 (mid-pack), create10k
103+
253.45 (preact-signals 287.4, lit 268.15 slower). CPU geomean 22.728 sits
104+
in the same band as vue 22.484 and svelte 22.195.
105+
- The finding was recorded in the baseline itself (#1219 closure comment,
106+
`v0.44.0-PERFORMANCE.md` diagnostic finding 1) as an algorithmic
107+
inefficiency, not a correctness break.
108+
109+
Disposition: the O(distance) move algorithm is accepted for Beta.1 admission
110+
because it is correct, linear, bounded and within the mainstream-framework
111+
band on its worst op. Move-algorithm optimization is a stated non-goal of
112+
#1225 and remains deferred to the evidence-gated B3.4 performance work.
113+
114+
### 3. Memory/listener/subscription growth (leaks) — CLEAR
115+
116+
Retention evidence:
117+
118+
- Micro churn: 25 cycles × 200 rows → 0 retained subscriptions, 0 retained
119+
listeners (`micro-evidence.json` stability section).
120+
- alpha.7 qualification: 100 churn cycles per scenario across all four
121+
scenarios → 0 retained subscriptions, 0 retained listeners
122+
(`benchmarks/v044/evidence.json`); the acceptance gate fails closed on any
123+
retention (`docs/current/v0.44.0-PERFORMANCE.md` acceptance contract).
124+
- Browser heap after run1k + clear ×5 with forced GC: 1,400,756 bytes vs
125+
1,219,651 ready (+14.8%) — memory returns to near-ready after clear, so
126+
there is no cumulative growth. Vanillajs equivalent: 748,157 vs 682,353
127+
(+9.6%). No leak signal for either.
128+
129+
Footprint context (not a leak): OE heap per row is ~2.3–5x vanillajs at 1k
130+
rows due to Region entry bookkeeping (baseline diagnostic finding 2). At the
131+
10k-row extension probe OE uses 9,511,356 bytes — below solid 10,570,464,
132+
svelte 11,603,029, vue 19,942,554 and preact-signals 38,801,488; above
133+
vanillajs 1,887,031 and lit 7,171,542. The micro churn `heapGrowthBytes`
134+
17,070,360 is a fake-DOM high-water reading without forced GC; the
135+
forced-GC browser probes above are the retention evidence and show return to
136+
baseline. The per-row footprint vs vanilla is carried as a documented
137+
trade-off under the same B3.4 evidence gate as finding 2; the blocker class
138+
as stated — growth/leaks — is CLEAR.
139+
140+
### 4. Claim providing no meaningful work reduction — ACCEPTED TRADE-OFF
141+
142+
Fake-DOM 1k-row table (`micro-evidence.json`): claim 10.387 ms vs fresh
143+
4.565 ms → claim/fresh ratio 2.275. On raw fake-DOM CPU time, claim is
144+
slower than bare fresh creation at this scale; that is documented in the
145+
baseline (finding 3) and not re-litigated here.
146+
147+
The work-reduction evidence on the axes claim exists for:
148+
149+
- Allocations: claim performs 0 allocations vs 10,031 for fresh creation of
150+
the same 1k-row table; 0 insertions/removals vs 10,031 insertions; 0
151+
writes vs 8,034 attr writes. Node creation and GC pressure are eliminated,
152+
not reduced.
153+
- Versus the 0.43.3 baseline architecture (`benchmarks/v044/evidence.json`):
154+
claim allocations drop from 10–40 to 0 per scenario and initial walk
155+
visits from 10–40 to 0; claim timing is at or below fresh in 3 of 4
156+
qualification scenarios (0.680/0.834, 0.243/0.287, 0.196/0.335 ms;
157+
nested-real-app 0.176 vs 0.147 ms).
158+
- Contract capability: the alternative to claim is not bare fresh creation
159+
but teardown of the server-rendered DOM plus fresh creation plus GC of its
160+
allocations, with loss of DOM identity and live state. Browser evidence:
161+
claim identity preserved and live value preserved on chromium, firefox and
162+
webkit, 0 page errors. Claim is the only path that satisfies the hydration
163+
contract (`docs/current/HYDRATION_CONTRACT.md`: the compiled claim
164+
artifact takes over the existing DOM in place).
165+
166+
Disposition: claim delivers meaningful, measured work reduction on the
167+
allocation, node-creation and tree-walk axes (to exactly zero) and provides
168+
identity/state preservation that fresh creation cannot provide at any cost.
169+
The 2.275x fake-DOM CPU ratio at 1k-row scale is accepted as a documented
170+
trade-off; claim-path CPU optimization is deferred to the evidence-gated
171+
B3.4 work. This is not "claim ≈ full rerender": rerender pays teardown +
172+
fresh + GC and loses identity; claim pays none of those.
173+
174+
### 5. Static route unexpectedly carrying mandatory runtime JS — CLEAR
175+
176+
`benchmarks/v044/evidence.json` staticOutput: runtimeBytes 0, scriptTags 0,
177+
transferredBytes 219. The alpha.7 acceptance gate fails closed unless static
178+
runtime bytes stay at 0, and it passes at the review SHA. A static route
179+
carries no mandatory runtime JavaScript.
180+
181+
## Overall admission verdict
182+
183+
No BLOCKER. The Alpha.10 diagnostic baseline shows no structural
184+
contradiction with the architecture: the exact Part update path is
185+
explained and competitive (CLEAR), there is no memory/listener/subscription
186+
growth (CLEAR), static routes carry zero mandatory runtime JS (CLEAR), and
187+
the two known inefficiencies — O(distance) keyed Region moves and the
188+
fake-DOM claim/fresh CPU ratio at 1k-row scale, together with the per-row
189+
heap footprint vs vanilla — are bounded, documented, non-catastrophic
190+
ACCEPTED TRADE-OFFs deferred to the evidence-gated B3.4 performance work.
191+
192+
This record satisfies the #1225 requirement for an explicit
193+
structural-regression verdict with evidence; per the issue's acceptance
194+
text, the verdict is to be recorded in the Beta.1 closure report by the
195+
owning role. This packet does not close #1225.
196+
197+
## Commands and exit codes (this review, at 17ec6a57)
198+
199+
- `git status` / `git log -1` → clean tree on `dev` at
200+
`17ec6a57610e9f4bdff090497ab34b973c884dfb` (exit 0)
201+
- `gh issue view 1225` / `gh issue view 1219` / `gh issue view 1150` → exit 0
202+
- `git diff --stat 493548a6..17ec6a57 -- packages/element/src
203+
packages/adapter-vite/src packages/app/src packages/ui/src
204+
packages/create/src` → empty output (exit 0)
205+
- `deno test -A benchmarks/` → exit 0 (12 passed, 0 failed)
206+
- `jq` re-extraction of all cited medians, memory probes and micro op counts
207+
from `benchmarks/jfb/evidence.json`, `benchmarks/v044/micro-evidence.json`
208+
and `benchmarks/v044/evidence.json` → all values match
209+
`docs/current/v0.44.0-PERFORMANCE.md` (exit 0)

0 commit comments

Comments
 (0)