# 增量渲染与性能

了解默认缓存、声明自定义依赖，以及如何测量实际更新成本。

大多数接入无需先调整缓存。保留稳定的消息标识和配置，让组件复用未变化的内容即可。本页用于添加自定义阅读贡献，或排查长文档更新成本。

## 默认会复用哪些内容

`QuireMarkdown` 和 `MdProse` 默认缓存完整顶层块的 Vue 投影。复用须同时满足原生 Tree
身份、源码位置、引用目的地、脚注编号/导航与渲染配置不变；后置定义仍可更新旧块。
正在增长的段落、列表或表格会重新投影，未实现表格行、单元格或嵌套块的独立缓存。
`:cache="false"` 可关闭投影缓存作对照，不影响增量解析。

## 自定义内容需要声明什么

自定义阅读贡献缺省保守重投影，因为 codec、render、load 都可能读取整篇文档。
`cacheKey(document)` 可声明节点外源码和外部状态的完整依赖，返回值用 `Object.is` 比较。
只有局部源码、attrs 与 locale 的贡献可以用 `cacheKey: () => null`，如上面的 Status 示例。
依赖某个引用目标时，应在 key 中包括解析状态和目标值；读取外部配置时应返回它的版本
或稳定身份。不要用常量 key 隐藏实际依赖。内置引用与脚注仍自动检查。
`renderNode` 对应 `renderNodeKey(state)`；未提供 key 时保守重投影全部块。
HTML 的 allowLink/allowImage 回调所在块也保持重投影，以持续观察响应式策略。

## 读取工作量与限制缓存

高级消费者可从 Vue 入口创建每个阅读实例独占的 `MarkdownRenderer`，调用
`renderer.render(state, locale, prefix, onError, options)` 并读取 `renderer.work`。
更换文档或卸载时调用 `clear()`，由 Vue 卸载负责释放资源；保持 onError 函数身份稳定。
`renderMarkdown(...)` 始终执行完整投影。默认缓存最多 2048 块、累计 2,000,000 个
UTF-16 源码单元，可通过构造参数 `maxBlocks/maxSourceUnits` 限制保留量；超额继续投影。
这些计数和预算不等于 JS 堆字节、解析耗时或浏览器绘制时间。

## 其他接入方式

本包不兼容早期 Incremark 的 API，算法差异见[与 Incremark 比较](/guide/comparison)；
remark/rehype 插件和 MDC 模板也需要独立适配。React 使用[独立适配包](/guide/react)共用解析与缓存规则；任意 HTML 模板执行与内容集合/路由不属于阅读入口。编辑器产品的 `MdProse` 共用本包阅读实现，
并继续提供它自己的图形节点与旧 API，见[MD Editor](https://msfe.quirekit.com/guide/md-editor)。


## 怎样复现性能对照

在生产构建中使用相同文档、20 个 UTF-16 单元 / 30ms 的追加序列，分别运行 cache=true/false；每种配置先预热，再重复测量。
两边都必须核对最终正文、链接目的地、脚注数量与回链，额外检查每个中间前缀和停止后的原文。

分别统计解析、VNode 投影、Vue 提交和强制布局。不要把回放总时长当作解析耗时，也不要把强制布局等同于浏览器绘制。
大型列表、表格或单段落仍可能是一个重投影块；顶层块遍历和全局引用检查仍存在，不能承诺每次追加恒定耗时。
`MarkdownRenderer.work` 只统计最近一轮投影工作；本站 Playground 不显示未经隔离的“引擎速度排名”。

旧工作树的测量不能代表当前发布版本。正式比较需同时记录源码版本、文档哈希、浏览器、硬件、预热与重复次数，并与正确性检查一起保存。
