Repository navigation
perf(preview): let render_markdown split its output into top-level blocks - #1023
Merged
Merged
Conversation
…ocks With `splitBlocks: true`, `render_markdown` writes `\0` on a line of its own between the top-level blocks of the document, so the preview can diff, process and sanitize block by block instead of the whole document after every typing pause. comrak still parses the whole document, so footnote numbers, reference links and heading-id dedupe are in each block's markup. No separator goes between footnote definitions (one `<section>`), nor inside a raw HTML element left open across blocks (`<details>` / markdown / `</details>`). No document can write the separator: comrak turns NUL into U+FFFD, and the math restore now does the same. Without the flag the output is byte-for-byte what it was; the export and the frontend do not pass it yet.
PathGao
force-pushed
the
perf/split-blocks-rust
branch
from
October 24, 2026 05:36
439317b to
ca76487
Compare
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.
In split view, every typing pause re-renders the whole document on the main thread: about 0.4 s per pause at 1 MB and 2.3 s at 5 MB, to change one paragraph. This is the first of three PRs that make a pause cost the size of the edit instead. This one only touches the renderer, and the frontend does not use it yet.
render_markdowntakes an optionalsplitBlocks. When it is true, the renderer writes\0on a line of its own between the top-level blocks of the document. comrak still parses the whole document, so footnote numbers, reference links and heading-id dedupe are already in each block's markup. The next PR diffs those blocks and processes and sanitizes only the ones that changed. StackEdit does the same thing: it renders the whole token stream with a marker at each section boundary, splits on it, and only sanitizes and inserts the sections that changed (markdownConversionSvc.js, editorSvc.js). VS Code (morphdom over a full render) and HedgeDoc 1 (anouterHTMLcompare of top-level elements) also re-parse the whole document and only touch what changed in the DOM. Neither one skips the full sanitize the way this does.Three blocks are kept whole:
<section class="footnotes">on the first definition and closes it after the last.<details>, then Markdown, then</details>. That is three top-level blocks to comrak and one element to the browser. The formatter counts the tags each raw HTML block opens and closes (void and self-closing tags excluded) and writes no separator while any are open. If an author's HTML never closes, the rest of the document becomes one block. That is slower but still correct.Without the flag the output is byte-for-byte what it was. That covers the export, which does not pass it. The tests pin this on all five UTF-8 samples.
PreviewFormatternow carries ausize, the open-tag count the split formatter keeps.convert_markdownis test-only now, and the source tests that read its body point atconvert_markdown_with.Verification:
cargo fmt --check,cargo clippy --all-targets -D warningsandcargo test(224 tests) pass. So donpm run check,npm testand vitest. New tests cover one separator per top-level block, footnotes as one block,<details>around Markdown, unclosed raw HTML, void tags, and that NUL in text, math and code cannot produce a separator.