Skip to content
QuireKit Markdown
Developer docs
Preview · unreleased

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.

QuireKit Markdown · QuireKitStreaming Markdown · @quirekit/incremark · MIT