perf: keep large markdown pastes fast and responsive#66
Open
DavertMik wants to merge 1 commit into
Open
Conversation
Pasting a large test document (~1000 blocks) froze the editor for ~1.6s. The cost was rendering, not parsing (~3ms): ~800 OverType editor instances mounted synchronously in a single main-thread task. - Lazily mount step editors (useDeferredMount): off-screen steps render a cheap static preview and upgrade to the interactive OverType editor when scrolled into view or clicked. A click both upgrades and focuses the field so editing starts on the first click; scroll/passive upgrades never steal focus. Freshly inserted empty steps still mount eagerly and autofocus. - Stream large pastes: insert the first screenful synchronously, then append the remaining blocks in idle-time batches so the main thread never blocks while a thousand-block document is built. - Avoid re-rendering every step on each keystroke: compute the step number and bail out of the state update when it is unchanged. - Debounce the demo's Markdown/JSON preview serialization so it runs once the document settles instead of on every streamed batch. Result on a ~1000-block paste (Chrome, measured): worst main-thread freeze 1651ms -> ~160ms, Total Blocking Time 1806ms -> ~140ms, time-to-first-content ~640ms -> ~80ms; OverType editors mounted on paste 801 -> 6 (rest mount on scroll). Adds regression tests for the behaviour that makes rendering fast: chunked paste (no synchronous full-document build), step-number correctness, and a sub-quadratic markdown parse guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deploying blocks with
|
| Latest commit: |
c1203a7
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://7e2aa228.blocks-cno.pages.dev |
| Branch Preview URL: | https://perf-large-markdown-paste.blocks-cno.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Pasting a large test document (the
become_a_tasker.test.mdsuite — ~58 KB, 1002 blocks: ~140 test steps, 162 headings, the rest paragraphs) froze the editor for ~1.6 s.Profiling (Chrome, real paste) showed the cost is rendering, not parsing.
markdownToBlockstakes only ~3–13 ms. The freeze came from mounting ~800 OverType editor instances (every step field is an OverType editor) synchronously in a single main-thread task.Changes
useDeferredMount) — off-screen steps render a cheap static preview and upgrade to the interactive OverType editor when scrolled into view or clicked. A click both upgrades and focuses the field, so editing starts on the first click; scroll/passive upgrades never steal focus. Freshly-inserted empty steps still mount eagerly and autofocus.createMarkdownPasteHandler) — insert the first screenful synchronously, then append the rest in idle-time batches so the main thread never blocks while a thousand-block document is built.App.tsx) — serialize Markdown/JSON once the document settles instead of on every streamed batch.Results (~1000-block paste, measured in Chrome)
Tests
All 167 unit tests pass;
tscclean. New regression guards (behavioural, not wall-clock, so CI-safe):createMarkdownPasteHandler.test.ts— a large paste is not built synchronously (only a bounded first chunk), and every block eventually streams in exactly once, in order.stepNumber.test.ts— step-numbering correctness (resets after non-step blocks, continues across blank lines).renderingPerf.test.ts— coarse parse-cost guard + a sub-quadratic scaling check.Notes
caretRangeFromPointif wanted.🤖 Generated with Claude Code