Skip to content

perf(editor): only serialize markdown on update when it is read - #9525

Merged
mejo- merged 1 commit into
mainfrom
perf/serializer
Nov 4, 2026
Merged

mejo- merged 1 commit into
mainfrom
perf/serializer

Conversation

@mejo-

@mejo- mejo- commented Nov 3, 2026

Copy link
Copy Markdown
Member

CollaborativeEditor serialized the whole document to markdown on every editor update to emit update:content, even when no listener uses the result. On large documents this blocks every keystroke, especially in Chromium where prosemirror-markdown's serializer is quadratic in the output size.

Emit the markdown as a getter so it is only serialized when a listener reads it.

Benchmark on a 500 kB markdown document (headings, paragraphs, lists with marks), headless browsers against a local instance, median per step, before -> after:

Chromium:

  • typing (cursor at start): 981 ms -> 67 ms
  • typing (cursor at end): 933 ms -> 34 ms
  • toggle bold on a word: 930 ms -> 50 ms
  • editor update handlers: ~870 ms -> <1 ms

Firefox:

  • typing (cursor at start): 125 ms -> 76 ms
  • typing (cursor at end): 55 ms -> 47 ms
  • toggle bold on a word: 67 ms -> 88 ms (within noise)
  • editor update handlers: ~9 ms -> 1 ms

Large tables are not affected by this change; their cost lies elsewhere.

Related to #908

Assisted-by: ClaudeCode:claude-opus-5-5

I also opened https://code.haverbeke.berlin/prosemirror/prosemirror-markdown/pulls/137 in prosemirror-markdown upstream that significantly improves serialization performance, especially in Chrome-based browsers.

🏁 Checklist

  • Code is properly formatted (npm run lint / npm run stylelint / composer run cs:check)
  • Sign-off message is added to all commits

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI tools
  • The AI-generated content was reviewed, comprehended and tested by a human

CollaborativeEditor serialized the whole document to markdown on every
editor update to emit `update:content`, even when no listener uses the
result. On large documents this blocks every keystroke, especially in
Chromium where prosemirror-markdown's serializer is quadratic in the
output size.

Emit the markdown as a getter so it is only serialized when a listener
reads it.

Benchmark on a 500 kB markdown document (headings, paragraphs, lists
with marks), headless browsers against a local instance, median per
step, before -> after:

Chromium:
- typing (cursor at start):  981 ms -> 67 ms
- typing (cursor at end):    933 ms -> 34 ms
- toggle bold on a word:     930 ms -> 50 ms
- editor update handlers:    ~870 ms -> <1 ms

Firefox:
- typing (cursor at start):  125 ms -> 76 ms
- typing (cursor at end):     55 ms -> 47 ms
- toggle bold on a word:      67 ms -> 88 ms (within noise)
- editor update handlers:     ~9 ms -> 1 ms

Large tables are not affected by this change; their cost lies elsewhere.

Related to #908

Signed-off-by: Jonas <jonas@freesources.org>
Assisted-by: ClaudeCode:claude-opus-5-5
@mejo- mejo- self-assigned this Nov 3, 2026
@github-project-automation github-project-automation Bot moved this to 🧭 Planning evaluation (don't pick) in 📝 Productivity team Nov 3, 2026
@mejo-

mejo- commented Nov 3, 2026

Copy link
Copy Markdown
Member Author

/backport to stable35

@nextcloud-command nextcloud-command added the AI assisted This PR contains AI-assisted commits label Nov 3, 2026
@mejo- mejo- moved this from 🧭 Planning evaluation (don't pick) to 👀 In review in 📝 Productivity team Nov 3, 2026
@mejo-
mejo- merged commit 5acc63b into main Nov 4, 2026
65 checks passed
@mejo-
mejo- deleted the perf/serializer branch November 4, 2026 08:18
@github-project-automation github-project-automation Bot moved this from 👀 In review to ☑️ Done in 📝 Productivity team Nov 4, 2026
@mejo-

mejo- commented Nov 4, 2026

Copy link
Copy Markdown
Member Author

/backport to stable34

@backportbot

backportbot Bot commented Nov 4, 2026

Copy link
Copy Markdown

The backport to stable34 failed. Please do this backport manually.

# Switch to the target branch and update it
git checkout stable34
git pull origin stable34

# Create the new backport branch
git checkout -b backport/9525/stable34

# Cherry pick the change from the commit sha1 of the change against the default branch
# This might cause conflicts, resolve them
git cherry-pick 1ad52013

# Push the cherry pick commit to the remote repository and open a pull request
git push origin backport/9525/stable34

Error: Failed to check for changes with origin/stable34: No changes found in backport branch


Learn more about backports at https://docs.nextcloud.com/server/stable/go.php?to=developer-backports.

@mejo-

mejo- commented Nov 4, 2026

Copy link
Copy Markdown
Member Author

Manual backport to stable34: #9543

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review AI assisted This PR contains AI-assisted commits performance 🚀

Projects

Status: ☑️ Done

Development

Successfully merging this pull request may close these issues.

3 participants