Incremental rendering and performance
Understand default caching, declare custom dependencies and measure update work.
Most integrations do not need cache tuning. Keep message identity and configuration stable so unchanged content can be reused. This page is for custom reading contributions and investigations into long-document update costs.
What is reused by default
QuireMarkdown and MdProse cache complete top-level Vue block projections by default.
Reuse requires identical native Tree identity, source positions, reference destinations,
footnote numbering/navigation and rendering configuration. Late definitions can still update
earlier blocks. Growing paragraphs, lists and tables are projected again; individual nested
blocks, table rows and cells have no independent cache. Use :cache="false" for a full-projection
comparison without disabling incremental parsing.
Declare custom dependencies
Custom reading contributions reproject conservatively by default, because their codec,
render and load functions can read the entire document. cacheKey(document) declares all
outside-node source and external-state dependencies; results are compared with Object.is.
Contributions that only read their own source, attrs and locale may return a constant key,
as the Status example does with cacheKey: () => null. For reference-dependent output, include
resolution status and target values; for external configuration, include its version or stable
identity. A constant must not hide actual dependencies. Built-in links and footnotes are still
checked automatically. renderNode has the equivalent renderNodeKey(state); without it,
all blocks reproject. HTML blocks with allowLink/allowImage callbacks also reproject so reactive
policy inputs continue to be observed.
Inspect work and bound retention
Advanced consumers can create one MarkdownRenderer per reader from the Vue entry, call
renderer.render(state, locale, prefix, onError, options), and inspect renderer.work.
Call clear() when replacing a document or unmounting; Vue unmounting releases resources.
Keep the onError function identity stable. renderMarkdown(...) always performs full projection.
Default retention is at most 2048 blocks and 2,000,000 UTF-16 source units, configurable through
constructor options maxBlocks/maxSourceUnits; exceeding a budget falls back to projection.
These counters and budgets do not measure heap bytes, parsing time or browser painting.
Other integration options
The package does not implement the earlier Incremark APIs; see the algorithm comparison.
remark/rehype plugins and MDC templates also need separate adaptation.
React uses a separate adapter over the shared parser and cache rules. Arbitrary HTML template execution and content collections/routing are outside the reading API. The editor's MdProse shares this reading implementation and retains its
product diagram nodes and existing API; see MD Editor.
Reproduce a comparison
Use a production build and identical documents with 20 UTF-16 units every 30ms. Compare cache=true and cache=false, warm up each mode, then repeat measurements. Verify final text, link destinations, footnote counts and backlinks in both modes; also inspect intermediate prefixes and retained source after stopping.
Measure parsing, VNode projection, Vue commits and forced layout separately. Playback duration is not parse time, and forced layout does not measure browser painting.
Large lists, tables and paragraphs may each remain a single reprojected block. Top-level traversal and global reference checks still exist; constant cost per chunk is not guaranteed.
MarkdownRenderer.work counts only the most recent projection. The Playground does not present an uncontrolled engine speed ranking.
Historical dirty-worktree measurements do not describe a current release. Record source revision, document hash, browser, hardware, warmups and repetitions alongside correctness results.