For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt, and this page is available as Markdown at /zh/guide/performance.md.
  • 中文
  • 性能与预算

    默认管线是同步的:解析与准备都在调用时完成。库不内置调度器、Worker 或虚拟列表;性能策略由宿主决定。本页给出可调的预算与常用的开销控制方式。

    成本在哪里

    阶段主要成本可以省掉吗
    解析上游 token 化、源码语法树、语义归一化不能;但可以缓存或放到 Worker
    准备克隆语义树、插件、HAST 转换、清洗与最终整理展示层变化时可以复用已有渲染快照
    渲染建立语义/HAST 索引、逐顶层块渲染与错误边界不能;大文档需要宿主分页

    retainSyntax: true 会保留源码语法树,显著增加内存与构建成本;只在需要源码坐标或 playground 语法树时开启。

    预算

    解析

    选项默认值说明
    maxSourceLength100,000LF 归一化后的源码长度
    maxSyntaxNodes50,000源码语法树节点数
    maxSemanticNodes50,000语义 AST 节点数
    maxDepth1,000语法树与语义树深度

    有效预算按“单次解析选项 → 创建时 defaults → 共享默认值”合并。非法值抛 INVALID_CONFIG,超限抛 SOURCE_TOO_LONG 或 SOURCE_TOO_COMPLEX。

    准备

    准备阶段的工作树与最终 HAST 使用固定预算,不能通过解析选项调整:

    预算上限
    语义工作树节点50,000
    语义工作树深度1,000
    HAST 节点50,000
    HAST 深度1,000

    这些值是防护阈值,不是性能目标。触发时准备阶段直接失败;库产生的合法快照总能被 restoreWikitextRenderDocument 恢复。

    模板展开

    选项默认值
    maxDepth40
    maxInvocations1,000
    maxExpandedLength与原始页面长度上限相同(100,000)

    把解析放到 Worker

    库不提供 Worker,但快照是普通数据,可以直接跨线程传递:

    // worker.ts
    import { parseWikitext } from "react-wikitext/parse";
    import { serializeWikitextDocument } from "react-wikitext/ast";
    
    self.onmessage = (event: MessageEvent<string>) => {
      const document = parseWikitext(event.data, { pageName: "Example" });
      self.postMessage(serializeWikitextDocument(document));
    };
    // main.ts
    import { restoreWikitextDocument } from "react-wikitext/ast";
    import { prepareWikitext } from "react-wikitext/hast";
    
    const document = restoreWikitextDocument(payload);
    const prepared = prepareWikitext(document);
    • 也可以把准备放进 Worker,传回渲染快照;渲染必须在主线程。
    • 传输前先确认快照版本;跨版本缓存应由恢复函数的校验结果判断是否可用。
    • 同一份源码重复发送时,缓存快照比重复解析更划算。

    缓存

    缓存键必须覆盖所有影响输出的输入:

    缓存键
    解析快照源码、pageName、站点配置、解析选项、解析器版本
    渲染快照解析快照键 + 解析函数、插件、policy、labels、headingIdStrategy、handlers

    快照内的 AST_SCHEMA_VERSION、SYNTAX_SCHEMA_VERSION 与 RENDER_SCHEMA_VERSION 变化意味着结构不兼容,应让缓存整体失效。缓存与恢复的安全边界见安全模型。

    避免重复工作

    • 把 parseOptions 与 prepareOptions 放在组件外,或用 useMemo 固定引用;内联对象会让 Wikitext 每次渲染都重新解析。
    • 解析器在模块加载时创建一次;配置变化时创建新解析器。
    • 只改组件或样式时复用渲染快照,不重新准备。
    • 不需要源码坐标时关闭 retainSyntax。
    • 服务端准备、客户端只渲染,可以减少浏览器下载与执行;见服务端与框架。

    按入口拆分打包

    入口加载解析器加载 React典型用途
    根入口是是客户端直接渲染
    /parse是否解析、Worker、构建期
    /expand是否模板展开
    /view否是只渲染准备好的快照
    /hast否否准备、序列化
    /ast否否AST 查询与数据处理

    只做展示时,客户端可以动态加载 /view,避免把解析器带进首屏包:

    async function loadViewer() {
      const [{ WikitextView }, { restoreWikitextRenderDocument }] = await Promise.all([
        import("react-wikitext/view"),
        import("react-wikitext/hast"),
      ]);
      return { WikitextView, restoreWikitextRenderDocument };
    }

    大文档

    • 100 KB 级别的密集文本可能阻塞主线程;优先放到 Worker,或按页拆请求。
    • 库没有虚拟列表;长页面由宿主分页、折叠或分段渲染。
    • 错误边界只隔离失败块,不减少整体渲染成本。
    • 目录、引用与分类是文档级结构,需要整份文档准备后才能生成。

    测量

    性能数字随源码、配置、浏览器与硬件变化,不在文档中固定。需要对比时运行仓库的 pnpm bench,并记录输入、解析器版本与改动前后的差异。