docs/solutions/performance-issues/2026-04-06-slate-v2-huge-document-paste-should-not-rerender-unchanged-descendants.md
The huge-document browser lane kept showing Slate v2 losing on paste even after the earlier clipboard and core insert experiments.
The trap was that the engine looked guilty because paste is an engine-shaped operation. The measurements said otherwise.
yarn bench:phase6:huge-document:local previously showed v2 paste around the
mid-70ms range while legacy sat around the high-40ms rangeslate-v2 showed insertFragment(...)
for the 200-line payload costing about 1.5msEditableBlocks rerendered unchanged trailing text segmentsslate-v2slate-v2Those cuts made the architecture cleaner, but they did not move the benchmark enough to keep.
Keep the engine path as-is and cut the runtime rerender churn in
editable-text-blocks.tsx:
EditableDescendantNode in React.memo(...)currentPathKey when the caller actually needs path-based
rendering data, such as renderElement or placeholder ownershipAdd a focused runtime proof in
runtime.tsx:
EditableBlocksMeasured result on the frozen huge-document lane after the kept cut:
48.13ms34.92ms-13.21msThat is a real win, not noise.
EditableBlocks only needs a structural rerender when the top-level runtime-id
list actually changes.
Before the fix, that structural rerender still forced the descendant render spine to do extra work:
EditableDescendantNodecurrentPathKey, so a prepend changed the
path for all existing top-level descendants even when their text and child
runtime ids were unchangedThat turned a top-level prepend into a broad React rerender even though the engine mutation itself was cheap.
After the fix:
So the runtime finally matches the transaction-first engine model instead of fighting it.