Skip to content

perf(rich-text): stop re-rendering links and embeds on every keystroke - #2261

Merged
Yves Rijckaert (YvesRijckaert) merged 1 commit into
masterfrom
perf/rich-text-rerenders
Oct 12, 2026
Merged

Yves Rijckaert (YvesRijckaert) merged 1 commit into
masterfrom
perf/rich-text-rerenders

Conversation

@YvesRijckaert

@YvesRijckaert Yves Rijckaert (YvesRijckaert) commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

What & why

Typing in large rich-text documents was slow because every link and embed re-rendered on every keystroke.

  • Links and embeds no longer re-render on every keystroke. They subscribed to the whole editor state. Hyperlinks now only watch whether the cursor is inside them; embeds only use the editor in click handlers.
  • Faster normalization. Plate's list normalizer looks up an unregistered taskList plugin on every node, and Plate deep-merges a throwaway plugin for each lookup. getType now returns the key directly for unregistered plugins, which is what Plate returned anyway.

Result

300-block document, master vs this branch:

Before After
Per keystroke ~265 ms ~15 ms
React commits per keystroke 316 16
Full normalize (2000 blocks) ~160 ms ~59 ms

No behaviour change: cards still update on outside value and entry changes, and "Edit link" still targets the right link after outside updates.

Tests

src/__tests__/performance.test.tsx fails if typing exceeds 18 commits per keystroke or normalizing looks up an unregistered plugin. Undoing any single fix fails it.

pluginAdapter.test.ts checks that the getType shortcut returns the same as Plate's own lookup, so a Plate upgrade that changes that fails CI.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
field-editors Ready Ready Preview Oct 12, 2026 7:23am UTC

Request Review

@wiz-inc-38d59fb8d7

wiz-inc-38d59fb8d7 Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Wiz Scan Summary

Scanner Findings
Vulnerability Finding Vulnerabilities -
Data Finding Sensitive Data -
Secret Finding Secrets -
IaC Misconfiguration IaC Misconfigurations -
SAST Finding SAST Findings -
Software Management Finding Software Management Findings -
Total -

View scan details in Wiz

To detect these findings earlier in the dev lifecycle, try the Wiz Code extension for VS Code, JetBrains, or Visual Studio.

Hyperlinks and embedded entry/resource elements subscribed to the full
editor state, so every keystroke re-rendered all of them. Hyperlinks now
select only whether the cursor is inside them; embeds use the editor ref.

Also skip Plate's slow plugin resolution for unregistered keys in
editor.getType. The list normalizer looks up `taskList` on every node.

Adds regression tests for commits per keystroke, unregistered plugin
lookups during normalization, and the getType shortcut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://vitest.dev/config/benchmark could be an alternative ;)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job :)

Merged via the queue into master with commit 142b81c Oct 12, 2026
17 checks passed
@YvesRijckaert
Yves Rijckaert (YvesRijckaert) deleted the perf/rich-text-rerenders branch October 12, 2026 08:39

This branch was successfully deployed

1 active deployment
Preview — 26979c94 Deployed Oct 12, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants