Conversation
This prevents querySelector × buttons calls on each selection change
Loading state for sandbox for delayed update
`discrete: true` forces synchronous execution - it prevents the update from being batched with other pending updates.
Instead of each table selection doing a separate `getEditorState().read()` we combine them into a single tableState() function, returning a combined object for the current state.
samuelpecher
left a comment
There was a problem hiding this comment.
A great step in the right direction. I particularly like the tableState extraction if we avoid any issues around batched updates potentially calling stale state.
| // fails because no root node detected. This is a workaround to deal with the issue. | ||
| requestAnimationFrame(() => this.editor?.update(() => { })) | ||
| }) | ||
| }, { discrete: true }) |
There was a problem hiding this comment.
I'm onboard with the idea here, especially removing the frame await, but this can't be a large part of the performance win since it's only on programmatic set value ?
Do we have a test that fails without the previous code, and then passes with { discrete: true } to be sure this handles the problem?
I'd also port the comment to explain the use of discrete
There was a problem hiding this comment.
I'll be honest, this was a suggestion from Claude, after analyzing Lexical+Lexxy code. Tests pass in all 3 variants, so we might not have a proper test for this?
77d51db to
bef9435
Compare
Performance and Memory Management Improvements for Lexxy
This PR addresses performance bottlenecks and memory leaks identified in Lexxy, particularly noticeable when editing large documents.
Key Changes
DOM Query Caching in Toolbar
querySelectorcalls per keystrokeTable State Consolidation
tableStategetterMemory Leak Fixes
destroy()method toCommandDispatcherwith proper cleanup of drag/drop handlers and command registrationsregisterUpdateListenerandregisterCommandcallsUpdate Listener Optimization
dirtyElementsanddirtyLeavesare both empty (no actual content changes)