perf: keep typing responsive in large docs (fixes #590)#789
Conversation
Edits that don't change a page's appearance no longer rewrite every PM-position attribute on that page; the page carries an in-memory position mapper and remaps on read instead. The full Document is now materialized on a debounce rather than on every keystroke.
|
@devmc12 is attempting to deploy a commit to the EigenPal Team on Vercel. A member of the Team first needs to authorize it. |
|
All contributors have signed the CLA ✍️ ✅ Posted by the CLA bot. |
|
I have read the CLA Document and I hereby sign the CLA |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The earlier api:extract ran against a stale dist and dropped insertImageFromFile / INSERT_IMAGE_MAX_WIDTH_PX from the snapshot. Re-extracted from a clean build so api:check passes.
…m-remap # Conflicts: # packages/core/src/layout-bridge/clickToPositionDom.ts
|
Thanks will have a look soon ! :) |
|
Closing this PR for now after a deeper React/Vue comparison. The investigation changed the diagnosis: Vue did not show the same large-document typing lag before these changes, so the primary bottleneck is not the shared virtualized page DOM / The React-specific hot path is heavier:
That path ran on every keystroke. In large documents, both |
|
Thansk for analysis @devmc12 ! Are you planning to look into react optimisation? |
Yes, I ran into this issue while using docx-editor-react, so I’m actively looking for a good fix. |
Summary
PmPositionMappercarries the offset delta and DOM readers remap positions on read viareadMappedPmStart/End.para:<paraId>) so inserting earlier content doesn't churn every later page's fingerprint into a full re-render.Documentmaterialization (onDocumentChange) is debounced (500ms); a new lightweightonEditorStateChange(state, tx)feeds per-transaction consumers (toolbar/outline) without walking the tree.All body PM-position readers (click-to-position, caret/selection rects, visual-line nav, scroll-to-position, cell-selection highlight, table-insert hover, image NodeSelection, RenderedDomContext) go through the mapper and are scoped to
.layout-page-content, so header/footer positions (a separate PM doc) are never remapped with the body mapper.Test plan
bun run typecheck,bun run api:check,bun run check:parity-contractrender-all-pages-now.test.ts— asserts 0 DOM mutations on visually-unchanged pages and correct remapped positionstext-editing.spec.ts(React)Known limitations
Only paragraph block ids are stable. Tables/images still use a counter id, so inserting content before them degrades those pages to the previous full-repaint path (no correctness issue — just less speedup).
Associated issues
#590 Editing becomes slow in large documents
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.