Skip to content

fix: highlight code beyond the first screen after a document opens - #697

Merged
Azganoth merged 1 commit into
mainfrom
bug/code-highlight-open
Oct 12, 2026
Merged

Azganoth merged 1 commit into
mainfrom
bug/code-highlight-open

Conversation

@Azganoth

Copy link
Copy Markdown
Owner

Summary

Opening a document highlighted every code block before the editor could respond, in one main-thread task, so a document made mostly of code missed #638's 3 s open budget from about 200 KB. Shiki's JavaScript regular-expression engine takes about half a millisecond per line of code, and highlighting was 81–82% of opening code documents in #680.

  • Creating the editor state highlights only the document's first 100 lines of code, enough to fill a tall window. The code highlight plugin's view highlights the remaining blocks afterwards in timer tasks of about 10 ms, each dispatched as a meta-only transaction outside history, starting from the block at the top of the viewport so code scrolled to is reached first.
  • The blocks still pending are positions mapped through every transaction. A block whose opening token a transaction deletes or replaces leaves the list, since that transaction already highlights whatever stands there; a pending block an edit has already highlighted is highlighted again in its turn, replacing its decorations. Mapping uses MapResult.deleted because ProseMirror also reports deletedAfter for a plain insertion at the position, which would drop a block whenever something was inserted right before it.
  • Timer tasks are used instead of requestIdleCallback: in the release WebView2 window on Windows 11, idle callbacks stopped firing altogether after a document opened, on main as well, while animation frames and timers ran.
  • Loading Limits in docs/specification.md now states a supported size of 200 KB, the largest size at which every shape Measure large documents again after the #638 fixes and set a supported size #680 measured meets both budgets: at 500 KB, tables miss the open budget and typing in a code block misses the keystroke budget. The specification also says a code-heavy document is shown before all of its code is highlighted, docs/architecture.md describes the mechanism, and CHANGELOG.md records the faster opening.

Related Issue

Closes #683

Verification

  • Focused tests mount an editor view with more than 100 lines of code and run its timers: the first block is highlighted at creation, the rest afterwards, and the result equals highlighting every block at once. The same comparison holds after editing, retyping, adding, removing, wrapping in a quote, inserting a paragraph before, and converting to a paragraph code blocks that are still pending. Further tests cover starting from the block at the top of the viewport and stopping when the view is destroyed. Mapping pending positions toward the start of an insertion, keeping positions whose opening token was deleted, not removing a re-highlighted block's earlier decorations, and ignoring the viewport each make them fail. The existing incremental highlighting tests pass unchanged.
  • pnpm check:frontend passed.

Manually verified in release builds on Windows 11, main and this branch both built from 9aa80f9 under a separate application identity with #680's method and fixtures, opening each fixture in a fresh process and typing 5 keystrokes per target:

  1. Opening code documents. "Shown" is when the document appears and the window responds; on main that is also when all of its code is highlighted.

    Code document main: shown Branch: shown Branch: all code highlighted Branch: longest frame meanwhile
    200 KB, 2 runs 3.42–3.62 s 0.82–0.94 s 4.2–4.8 s 59 ms
    500 KB, 2 runs 7.60–10.77 s 1.00–1.14 s 9.6–11.4 s 70 ms
    1 MB, 1 run 22.3 s 1.66 s 28.1 s 85 ms
  2. Keystrokes after highlighting finished took as long on both builds: a median paint of 32–48 ms in a paragraph and 80–88 ms in a code block at 200 KB, and 136–224 ms in a code block at 500 KB.

Not verified: the release timings on top of #693, which main gained after they were taken; scrolling during the background pass; and how the pass behaves in a window behind others or minimized.

Notes

  • At 1 MB, the background pass finishes later than main's single freeze did, because every slice's transaction redraws the editor; a CPU profile puts about a quarter of the pass there, mostly in ProseMirror's DecorationSet.forChild walking the decoration set once per top-level node, which every keystroke pays as well.
  • A faster engine was measured but not taken: Shiki's Oniguruma engine highlighted the 200 KB fixture about 3.3 times faster in Node, but it is WebAssembly, which the content security policy would have to allow, and highlighting would still grow with the document.

@Azganoth Azganoth added the Bug Something isn't working label Oct 12, 2026
@Azganoth Azganoth self-assigned this Oct 12, 2026
@Azganoth
Azganoth merged commit e223abb into main Oct 12, 2026
3 checks passed
@Azganoth
Azganoth deleted the bug/code-highlight-open branch October 12, 2026 23:09
@Azganoth Azganoth mentioned this pull request Oct 12, 2026
8 of 9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Opening a document highlights every code block before the editor responds

1 participant