Skip to content

perf(preview): batch a first render and regroup only the sections an edit touched - #1025

Merged
PathGao merged 1 commit into
perf/patch-changed-blocksfrom
perf/preview-patch-followups
Oct 24, 2026
Merged

PathGao merged 1 commit into
perf/patch-changed-blocksfrom
perf/preview-patch-followups

Conversation

@PathGao

@PathGao PathGao commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

This PR builds on the previous one and fixes the two places where the block patch was still worse than it should be.

Opening a large file got slower. A first render sanitized every block with its own DOMPurify call, and each call builds its own document, so a 5 MB file opened about 30% slower than on master. A first render, and any multi-block edit, now processes and sanitizes all its blocks in one pass. Each block goes in inside a <section> carrying a random nonce and is taken back out afterwards. Markup that closes the section early or forges one cannot know the nonce. The count or a nonce then comes out wrong, and that batch falls back to one block at a time. A test pins this with a forged marker.

Adding a section regrouped the whole document. Adding, removing or re-levelling a top-level heading moved every block back to the top level and wrapped them all again. Every fold wrapper was then new, so the fold layout observer re-measured all of them. Now only the sections between the nearest heading of the edited level or higher before the edit and the next one after it are regrouped. A section of a higher level contains the change unchanged, and one of the same level ends where it did. Wrappers outside keep their identity, and a kept heading's new wrapper takes on the folded state the reader left it in.

Same harness as the previous PR, median of 2-4 runs:

200 KB 1 MB 5 MB
first render: master / previous PR / this PR 97 / 111 / 84 ms 458 / 606 / 428 ms 2332 / 3005 / 2330-2540 ms
a new ## section: master / previous PR / this PR 80 / 5 / 1 ms 424 / 29-70 / 4 ms 2324 / 173-398 / 27 ms
a keystroke: master / this PR 82 / 1 ms 430 / 4 ms 2246 / 22 ms
Enter at the top: master / this PR 82 / 10 ms 434 / 47 ms 2414 / 260 ms

Left out: rewriting data-sourcepos lazily, as a per-block line offset, instead of onto every node below an Enter. That would be the remaining O(document) step, about 260 ms at 5 MB. It is not small. Every reader of data-sourcepos would have to resolve the offset: scroll sync and anchor restore in previewAnchor.ts, the line mapping in lineCoordinates.ts, and the task checkbox toggle. So it is not in this stack.

Risks: same as the previous PR. Not yet verified in the real Tauri app.

Tests: the parity spec gains a new subsection, a new top-level heading and a heading that changed level. previewPatch.spec.ts gains these cases:

  • A subsection that leaves the surrounding sections' wrappers alone and keeps a closed section closed.
  • A same-level section that re-wraps only the section it splits.
  • The forged batch marker.

npm run check, npm test, vitest (583), and cargo fmt/clippy/test pass.

@PathGao
PathGao added this pull request to stack #1026 October 23, 2026 20:22
…edit touched

A first render sanitized every block with a call of its own, and each
DOMPurify call builds a document of its own: a 5MB file opened about 30%
slower than with the whole-document pipeline. Blocks are now processed
and sanitized in one pass, each inside a <section> carrying a nonce, and
taken back out of it; markup that closes or forges one cannot know the
nonce, so that batch falls back to one block at a time.

Adding, removing or re-levelling a top-level heading moved every block
in the document back to the top and wrapped them all again. Only the
sections between the nearest heading of the edited level or higher
before the edit and the next one after it are regrouped now; the folds
outside keep their wrappers, and a kept heading's wrapper takes on the
state the reader left it in.
@PathGao
PathGao force-pushed the perf/preview-patch-followups branch from c77ae18 to 9e7ccc8 Compare October 24, 2026 05:36
@PathGao
PathGao merged commit 2035432 into master Oct 24, 2026
3 of 4 checks passed
@PathGao
PathGao deleted the perf/preview-patch-followups branch October 24, 2026 06:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant