-
Notifications
You must be signed in to change notification settings - Fork 62
fix: batch track changes processing for improved comments loading performance #1864
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b30243a5c3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (COMMENT_EVENTS?.BATCH_ADD && type === COMMENT_EVENTS.BATCH_ADD && batchComments?.length) { | ||
| batchComments.forEach((trackedChangeParams) => { | ||
| handleTrackedChangeUpdate({ superdoc: proxy.$superdoc, params: trackedChangeParams }); | ||
| }); | ||
|
|
||
| return; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forward batch comment updates to user callback
When a DOCX import (or any batched tracked-change load) emits BATCH_ADD, onEditorCommentsUpdate returns early and skips the config.onCommentsUpdate callback. Previously, each tracked-change add event bubbled up to user code; now integrations that rely on onCommentsUpdate (e.g., external comment sidebars, analytics, or sync hooks) will never be notified for these batch-created comments. This is a behavior regression specific to batched track-change loads and can leave external consumers out of sync.
Useful? React with 👍 / 👎.
b30243a to
5667d87
Compare
Add new event constant to support batching multiple track change comments into a single event emission, enabling performance optimizations for bulk operations.
Optimize comments loading performance for documents with many tracked changes by batching all track change processing into a single ProseMirror transaction dispatch. - Collect all track changes before dispatching instead of dispatching inside forEach loop - Add batchedTrackChanges transaction metadata for bulk processing - Extract processSingleTrackChange helper for code reuse - Emit single BATCH_ADD event with all comments instead of individual ADD events Reduces 827 dispatches to 1 for documents with ~800 tracked changes, improving load time from 5+ seconds to near-instant.
Add handler in onEditorCommentsUpdate to process batched track change comments from the new BATCH_ADD event type, iterating through all comments and applying handleTrackedChangeUpdate for each.
- Fix existing test expectation for handleTrackedChangeTransaction return value when no marks provided - Add test for processing batched track changes with BATCH_ADD event - Add test for handling empty batchedTrackChanges array - Add test for filtering invalid track changes in batch
5667d87 to
191a434
Compare
Hey Superdoc team 👋🏽
I was learning more about the project and saw this issue (#1721) related to the performance of the document when there are a lot of tracked changes.
I was able to identify 2 different problems:
This PR has a simple fix for the 1st issue. I started investigating also the 2nd, but it seems more complex.
I went ahead and implemented this fix, mostly because I wanted to learn more how the editor works, but I'm opening the PR because it might be useful to the project. (I don't mean to go over the team's development process, so no worries if this can't be merged 😅)
Summary
This PR fixes a critical performance issue where documents with many tracked changes (e.g., 800+ changes) took over 5 seconds to load comments. The root cause was identified as 827 individual ProseMirror transactions being dispatched in a loop, each triggering a full document traversal and UI update cycle.
Before: 827 dispatches → 5+ seconds load time
After: 1 dispatch → < 1s load time
before.mp4
now.mp4
Problem Analysis
Symptoms
Root Cause
In
comments-store.js, thecreateCommentForTrackChangesfunction was iterating over grouped track changes and dispatching a separate ProseMirror transaction for each one:Each
dispatch(tr)call:Multiplied by 827 iterations, this created a severe performance bottleneck.
Solution
Approach
Batch all track changes into a single transaction and process them in one pass through the comments plugin.
Implementation
1. Collect Track Changes Before Dispatching
File:
packages/superdoc/src/stores/comments-store.jsInstead of dispatching inside the loop, collect all track changes that need processing:
2. Handle Batched Track Changes in Plugin
File:
packages/super-editor/src/extensions/comment/comments-plugin.jsModified
handleTrackedChangeTransactionto detect and process batched track changes:3. Extract Reusable Processing Logic
File:
packages/super-editor/src/extensions/comment/comments-plugin.jsCreated
processSingleTrackChangehelper to handle both batched and single track change scenarios without code duplication:4. Add New Event Type
File:
shared/common/event-types.tsAdded
BATCH_ADDevent type for the new batched comment creation:5. Handle Batch Event in Vue Component
File:
packages/superdoc/src/SuperDoc.vueAdded handler for the new
BATCH_ADDevent:Files Changed
packages/superdoc/src/stores/comments-store.jscreateCommentForTrackChangesto batch all track changes into single dispatchpackages/super-editor/src/extensions/comment/comments-plugin.jsprocessSingleTrackChangehelper, modifiedhandleTrackedChangeTransactionto handle batched track changesshared/common/event-types.tsBATCH_ADDevent constantpackages/superdoc/src/SuperDoc.vueBATCH_ADDevent inonEditorCommentsUpdatepackages/super-editor/src/extensions/comment/comments-plugin.test.jsTesting
Existing Test Fix
handleTrackedChangeTransaction returns original state when no marks providedtrackedChangesinstead ofundefinedwhen no marks providedtoBeUndefined()totoEqual({ existing: 'value' })New Tests Added
handleTrackedChangeTransaction processes batched track changes and emits single BATCH_ADD eventBATCH_ADDevent is emitted with all commentshandleTrackedChangeTransaction handles empty batchedTrackChanges arrayhandleTrackedChangeTransaction filters out invalid track changes in batch