perf(domformat): preserve sparse prepared-state publication - #88
Open
alowpoly wants to merge 6 commits into
Open
perf(domformat): preserve sparse prepared-state publication#88alowpoly wants to merge 6 commits into
alowpoly wants to merge 6 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Outcome
The ordinary adjacent paged hot path is genuinely proportional to declared changes. Sparse playback and variant stages borrow validated resident-page ranges, mutate only those targets in canonical state, and publish only those targets. Adjacent surface/profile publication reuses typed scratch storage. Complete reconstruction remains only at semantic barriers and failure recovery where an absolute row is required.
No public API, codec, transport, renderer, producer, adapter integration, or Worker surface is added. Flowerbox is intentionally excluded. Synthetic dimensions are informed only by the pinned published Cloth, Solitaire, and Gravity Well sources.
Runtime changes
Adversarial follow-up
Two independent adversarial passes were applied after the sparse implementation. The final follow-up at
16dd34b3closes the reproduced transactional/recovery gaps:advanceManycommit failure publishes its successfully committed prefix coherently before rethrowing, so retry cannot strand stale DOMTrace evidence is now fail-closed: Chromium uses
recordAsMuchAsPossible, records a bounded three-category set, requiresdataLossOccurred === false, preserves raw events before interpretation, and requires positiveRunTask containing FireIdleCallbackattribution before applying the unchanged 50 ms page-preparation limit. General RunTask/cadence observations are intentionally not hard gates.Visit and allocation evidence
The bounded TypeScript source audit reports 30 forbidden source-form sites at
b3b30bbb→ 0. The candidate guard is broader now: 14 named scopes, including the adjacent helper call boundaries, with fail-closed helper-renaming and mutation tests. It rejects typed/ordinary slices,Array.from, array/typed-array constructors, array literals/spreads, Set/Map, sorting, and nested closures in those named scopes.This is a bounded source-form tripwire, not general JavaScript heap instrumentation. Sparse staging still creates bounded stage objects; the claim is no guarded target-sized collection/source forms in the named sequential paths.
Remaining full scans are intentional:
Chromium trace evidence
The original performance comparison alternated five independent 42-second runs per revision (
b3b30bbbbaseline versus315447b9candidate). Those runs support reduced JavaScript publication work, not a blanket cadence speedup:Mean inclusive attribution changed as follows:
FunctionCall: 500.843 ms → 407.385 ms (-18.66%)FireAnimationFrame: 657.425 ms → 550.376 ms (-16.28%)Layerize: 7,199.469 ms → 7,189.294 ms (-0.14%)Commit: 2,442.976 ms → 2,436.316 ms (-0.27%)Paint: 1,471.029 ms → 1,469.486 ms (-0.10%)The final recovery/evidence follow-up was then traced twice from the identical 101,464-byte tarball (
93b3dba91608c9a7cd4aeb8928f15f544bda6df34335f387a9b0f9ec6de19f75): once during release and once from clean commit16dd34b3.The clean run crossed 6/12/11 timing-window page boundaries for Cloth/Solitaire/Gravity Well and at least 2/4/4 boundaries in the separate instrumented visit windows. Stable DOM identity held throughout. Remaining gaps were dominated by
Layerize,Commit, andPaint, not sparse publication or page validation.The clean run verified the exact published cssGraphics source manifest at
083532aa66599f1ff4618b987ccc5df462631996(Cloth client/shadow patch, Gravity Well prepared playback, and Solitaire prepared playback). No adapter code is executed by the synthetic trace and no adapter behavior/performance parity is claimed.Correctness and visual parity
Verification
pnpm --filter @layoutit/polycss-domformat test:coverage— 316/316; 96.69% lines, 92.02% branches, 94.65% functionspnpm --filter @layoutit/polycss-domformat test:page-preparation— passpnpm --filter @layoutit/polycss-domformat test:release— passpnpm gallery:domformat:verify— 304 models / 199,847 leavespnpm test— passpnpm build— passpnpm check:readmes— passpnpm test:scripts— 22/22git diff --check— passDeterministic packed package: 101,464 bytes, below the unchanged 100 KiB ceiling; unpacked size 375,793 bytes. The package is deterministic, runtime-only, install-smoke-tested, CLI/type-declaration tested, and accepts the independent producer.
Worker follow-up
A separate Worker-preparation PR is not currently justified. Attributed preparation tasks remained below 17 ms in the full release matrix and 5.302 ms in the final publication traces, leaving substantial headroom under the unchanged 50 ms gate. A Worker proposal should wait for a fresh trace showing validation itself as a material main-thread bottleneck.