Performance — measured, budgeted, reproducible
Measured 2026-07-05 on the 10MB torture document (527,671 lines — the full
golden corpus repeated to 10MB: headings, tables, code, footnotes, CJK, deep
nesting). Reproduce: npx tsx testing/benchmarks/src/bench.ts.
| Operation | Measured | Budget (CI-enforced) |
|---|---|---|
Typing latency, state.apply p95 @10MB | < 0.01ms | 16ms |
| Serialize 10MB document to markdown | 2.2s | 5s |
| Parse (open) 10MB markdown | 18.8s | 25s |
| Parse 100KB (a huge README) | ~90ms | — |
| Parse 1MB | ~1.0s | — |
The interesting engineering story
Markdown parsers that resolve emphasis/links over a whole-document token buffer (micromark’s architecture — the price of its exactness) scale superlinearly: our first measurement of the 10MB document was 361 seconds. Editors usually “solve” this by capping document size or using a sloppier parser.
Inkroom instead parses large documents in chunks cut at provably safe
block boundaries — a scanner tracks code fences, all five multi-line HTML
block types and front matter, so a cut can never land inside a construct;
document-global constructs (link reference definitions, footnotes) are
shared across chunks and deduplicated after the merge. Each piece stays in
the parser’s fast region: 361s → 18.8s, and equivalence with the
single-shot parse is enforced by tests, not asserted in a comment
(packages/markdown/src/chunk.test.ts).
Typing was never the problem: ProseMirror transactions are O(change), not O(document) — at ten megabytes, applying a keystroke to the document model costs microseconds, and the view only re-renders the touched DOM.
What the budgets mean in practice
- A 10MB file is ~40× War and Peace in markdown. Real documents (README, wiki page, spec, book chapter) open in tens of milliseconds.
- The keystroke budget (16ms = one 60fps frame) is spent almost entirely in the browser’s paint, not in Inkroom.
- The markdown source mode disables its syntax highlighting above 20,000 lines to protect the frame budget (a viewport-scoped highlighter lifts this limit in a minor release).