Context
Split out of #16533 at review of PR #16534, so two acceptance criteria survive the close rather than retiring silently with it.
The fix is correct and shipping — a live, user-reported animation regression should not wait on a guard that protects against a future reintroduction. But the guard genuinely matters here, because this defect's own history is that reintroduction.
The Problem
The per-move forced layout came from ac231036b5 (#12894, closing #12883) — a grid column-drag repair for Chromium's stale moveBefore flex layout, applied to every moveNode rather than scoped to the case it fixed. Cost scales with the parent's child count, so it was invisible at grid N and quadratic at helix N: 8137ms of blocked main thread on a 590-item reorder against 18ms without it.
Nothing currently fails if someone reintroduces a per-move layout flush. The two ACs below were written to close that, and PR #16534 does not deliver them.
The Fix — and do NOT implement AC1 literally
#16533 AC1 asks for "a timing assertion that fails against the current per-move heal". A wall-clock timing assertion in CI is flaky by construction and will be quarantined within a month, at which point the guarantee is gone and the file still looks covered.
The deterministic form of the same guarantee is structural:
- a batch of N
moveNode deltas against one parent produces exactly one heal, not N
moveNode itself never touches parentNode.style.display
Both fail against the per-move form for the right reason, and neither can flake. Assert the shape that made it quadratic, not the wall-clock symptom.
Worth also pinning, since they are the properties a future refactor would silently drop:
- the drain runs even when a delta throws mid-batch (
finally)
- a parent skipped by the animation gate is not healed, and the batch does not strand it into the next one
Acceptance Criteria
Out of Scope
- The fix itself — PR #16534.
- Visual/animation confirmation, which needs a visible tab; that is
#16533's post-merge validation and blocked by the harness reporting document.hidden: true on a fronted tab.
- The
getAnimations({subtree: true}) cost on large pending sets.
Related
#16533 / PR #16534 (the fix) · #12894 / #12883 (heal origin) · #8620
Origin Session ID: c724a85f-2d37-44ac-9a33-12dcce415aa2
Context
Split out of
#16533at review of PR #16534, so two acceptance criteria survive the close rather than retiring silently with it.The fix is correct and shipping — a live, user-reported animation regression should not wait on a guard that protects against a future reintroduction. But the guard genuinely matters here, because this defect's own history is that reintroduction.
The Problem
The per-move forced layout came from
ac231036b5(#12894, closing#12883) — a grid column-drag repair for Chromium's stalemoveBeforeflex layout, applied to everymoveNoderather than scoped to the case it fixed. Cost scales with the parent's child count, so it was invisible at grid N and quadratic at helix N: 8137ms of blocked main thread on a 590-item reorder against 18ms without it.Nothing currently fails if someone reintroduces a per-move layout flush. The two ACs below were written to close that, and PR #16534 does not deliver them.
The Fix — and do NOT implement AC1 literally
#16533AC1 asks for "a timing assertion that fails against the current per-move heal". A wall-clock timing assertion in CI is flaky by construction and will be quarantined within a month, at which point the guarantee is gone and the file still looks covered.The deterministic form of the same guarantee is structural:
moveNodedeltas against one parent produces exactly one heal, not NmoveNodeitself never touchesparentNode.style.displayBoth fail against the per-move form for the right reason, and neither can flake. Assert the shape that made it quadratic, not the wall-clock symptom.
Worth also pinning, since they are the properties a future refactor would silently drop:
finally)Acceptance Criteria
moveNodenever performs a layout flush inline; the only flush site is the batch drain.#12883stays fixed: a grid column drag to the locked-end region still re-homes correctly.Out of Scope
#16533's post-merge validation and blocked by the harness reportingdocument.hidden: trueon a fronted tab.getAnimations({subtree: true})cost on large pending sets.Related
#16533/ PR #16534 (the fix) ·#12894/#12883(heal origin) ·#8620Origin Session ID: c724a85f-2d37-44ac-9a33-12dcce415aa2