Plate 的 Slate AR Perf:Slate v2 性能优化车道、基准目标注册表与最快安全停止规则
【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate
在 Plate 仓库中,slate-ar-perf是为 Slate v2 性能工作设计的 Agent 技能(skill),它把“再试一个优化”从拍脑袋的架构讨论变成一条可测量的循环:每个优化动作(packet)都要跑基准命令、打印METRIC name=value指标行,并通过原生编辑器行为正确性检查后才能被保留。读完本文,你将理解这条性能车道与slate-ar/Codex Autoresearch 的分层关系、目标注册表benchmarks/targets/slate-v2.json的完整契约结构、分页/虚拟化与大文档全选两套默认性能契约,以及“最快安全(fastest-safe)”的停止条件与正确性闸门。
一、车道定位:在测量循环之上叠加性能策略
.agents/skills/slate-ar-perf/SKILL.md 的 frontmatter 将其描述为:“Slate v2 performance lane for Codex Autoresearch. Delegates generic loop mechanics to slate-ar/codex-autoresearch and adds target registry, fastest-safe stop rules, exactness gates, and pagination/virtualization defaults.”
这句话精确刻画了三层层级关系:
| 层级 | 组件 | 职责 |
|---|---|---|
| 通用状态机 | codex-autoresearch:codex-autoresearch | 包(packet)生命周期、日志、dashboard、深度研究、质量缺口、漂移、finalize、CLI 机制 |
| Slate 包装层 | slate-ar | Slate v2 专属默认值:目标 cwd(.tmp/slate-v2)、会话文件(.tmp/slate-v2/autoresearch.*)、dashboard/status/finalization 入口、正确性路由 |
| 性能车道 | slate-ar-perf | 性能目标策略、基准注册表、精确性闸门(exactness gate)、最快安全停止规则、分页/虚拟化默认契约 |
SKILL.md 明确要求不要在这层重复通用的 packet/dashboard/finalization 机制:
Do not duplicate generic packet/dashboard/finalization mechanics here. Load
slate-arfor Slate wrapper behavior andcodex-autoresearch:codex-autoresearchfor the underlying Autoresearch state machine.
从源码结构看,这条车道还有一个日常入口 slate-ar-fast:它负责“挑选或创建最热的性能目标,然后运行slate-ar-perf”,并内置了与slate-ar-perf一致的无回归规则(No-Regression Rule)和停止规则(Stop Rules),可视为slate-ar-perf面向“让我把它变快”这类模糊指令的快捷封装。
二、适用边界:何时走这条车道,何时绕行
SKILL.md 用两节清单划定了路由边界,这是整个技能体系里避免“性能车道吃掉正确性修复”的关键设计。
适用(Use When):
- 用户显式调用
slate-ar-perf; - 用户说出
fast、fastest、max perf、pagination、virtualization、benchmark等关键词,或要求让某个 Slate v2 表面变快; - 分页、虚拟化、超大文档、表格、渲染、布局、选区、打字、粘贴、滚动或挂载性能需要迭代优化;
- 存在(或应该存在)一个能打印
METRIC name=value的基准命令; - 下一步动作取决于测量结果,而不只是架构判断。
不适用(Do Not Use When):
| 场景 | 应改用 | 原因 |
|---|---|---|
| 问题本质是正确性 bug,需要直接修复 | slate-patch | 性能循环会掩盖缺失的 oracle |
| 目标过于模糊,无法推断基准与正确性契约 | slate-ar-recipe(目标发现)或slate-plan(架构框架) | 没有可测量的决策问题 |
| 产出是供用户评审的架构/API 提案 | slate-plan | 这是提案而非优化循环 |
| 目标是 Plate 产品代码而非裸 Slate v2 | — | 该车道只覆盖 raw Slate v2 |
三、自然模式与“最快安全”停止规则
slate-ar-perf定义了三种自然模式:
fast/fastest/max perf/make it fastest(最快安全模式):挑选或恢复匹配的目标,持续运行 packet,直到命中以下任一停止条件:- 达到目标 parity(与基线/遗留实现打平或反超);
- 平台期(plateau);
- 正确性阻塞;
- 架构阻塞(剩余收益需要 API/运行时重构,超出本车道);
- 不安全的 finalize / 脏工作树边界;
- 用户中断。
pagination/virtualization:除非用户给出更精确的目标,否则直接套用本文第五节的分页默认契约。continue/resume/status/dashboard/finalize:委托给slate-ar的操作员模式,随后对下一个 packet 应用性能策略。
其中 plateau 有精确定义:
Plateau means three consecutive valid correctness-green packets improve the primary metric by less than 5% and no safe P0/P1 profiler hypothesis remains.Do not stop at the first win.
即:连续 3 个有效且正确性全绿的 packet 对主指标的提升都小于 5%,且不再有安全的 P0/P1 级 profiler 假设可验证。这个定义同时被 slate-ar-fast 的 Stop Rules 继承,其停止条件还包括“目标阈值达成且 checks 全绿”“与 legacy 的 parity 达成”“下一个安全收益需要slate-plan”。
四、目标注册表:slate-v2.json 是迁移脊柱
4.1 注册表的地位与默认路径
SKILL.md 指定 benchmarks/targets/slate-v2.json 为性能决策的“migration spine”(迁移脊柱),它是基准问题、队列(cohort)、命令、指标、正确性检查、产物(artifact)与佐证文档的唯一事实来源。默认操作路径分 6 步:
# 1. 列出全部目标 pnpm bench:targets:list # 2. 检查注册表健康 pnpm bench:targets:check # 3. 生成或检查目标报告 pnpm bench:targets:report # 4. 对目标做只读 dry-run pnpm bench:targets:dry-run -- <target-id> # 5. 仅在有真实需要时初始化 .tmp/slate-v2/autoresearch.* 会话 node tooling/scripts/bench-targets.mjs autoresearch-init <target-id> # 6. 交给 slate-ar / Codex Autoresearch 做 setup 检查、基准 lint、 # checks 检查、packets、stale-run 检测、ASI、dashboard、keep/discard 决策与最终证据这些脚本在 package.json 中对应bench:targets:*一族,最终都落到 tooling/scripts/bench-targets.mjs(约 566 行)。从源码结构看:
listTargets()(L196 起)按 id 排序后逐行打印id、family、primary metric、command四列,这正是pnpm bench:targets:list的输出形态;validateRegistry()(L143-L194)实现了注册表健康检查:version必须为 1、targets非空、每个目标必须有id/question/owner/family/cwd/command、id 不得重复、cwd与artifacts[].path必须是仓库相对路径、metrics.primary必填、metrics.direction只能是lower/higher、metrics.printsMetric必须是布尔值、correctness.command必填、artifacts非空——pnpm bench:targets:check就是在跑这套校验;- 脚本还内置了 Evidence Kit(
benchmarks/editor/research/benchmark-registry.json)的导入逻辑(importEvidenceKit,L104-L121),把遗留证据库的 artifact 行机械地转换成目标注册表条目,并打上migration.importedFrom溯源标记。
4.2 目标契约的字段结构
benchmarks/targets/README.md 定义了每个目标的完整契约字段:
id:面向命令的稳定 id;question:该基准回答的决策问题;owner:运行时/包责任人;family与kind:报告分组(如react-large-document/browser-trace);cwd与command:仓库相对的运行位置与完整命令;metrics:主指标、方向(lower/higher)、单位,以及输出是否打印METRIC name=value(printsMetric);correctness:防止“提速”破坏编辑器行为的命令;artifacts:目标产生的结果文件;docs:佐证证据链接;thresholds:promotion/stretch/plateau 阈值;migration:Evidence Kit 退役期间的临时溯源字段。
当前注册表中共有 27 个目标(见 benchmarks/targets/reports/slate-v2.md 的 Summary:Targets: 27,Required artifacts 25,Missing required artifacts 0),覆盖react-large-document、react-pagination、react-locality、core-current、core-compare、history、clipboard、collaboration、issue-replay等 family。
4.3 两个真实目标条目示例
分页虚拟化(与本文第五节契约直接对应)——react-pagination-virtualized-char-burst:
{ "id": "react-pagination-virtualized-char-burst", "question": "Does rows=800 virtualized pagination keep char-burst typing near staged table performance while DOM and page mounts stay bounded?", "owner": "slate-v2", "family": "react-pagination", "kind": "browser-trace", "cwd": ".tmp/slate-v2", "command": "bun run bench:react:pagination-virtualized-char-burst:local", "metrics": { "primary": "pagination_virtualized_vs_table_ratio", "direction": "lower", "unit": "ratio", "printsMetric": true, "upgrade": "Primary metric compares rows=800 virtualized burst latency against the staged 500-row table burst in the same benchmark run." }, "correctness": { "command": "PLAYWRIGHT_RETRIES=0 PLAYWRIGHT_WORKERS=1 bun playwright test playwright/integration/examples/pagination.test.ts --project=chromium -g \"keeps rows=800 virtualized pagination in the staged-class perf envelope|...\"", "policy": "Promotion requires virtualized burst perf plus native pagination selection/editing correctness." }, "artifacts": [ { "path": ".tmp/slate-v2/tmp/slate-pagination-virtualized-char-burst-benchmark.json", "required": true } ] }这个条目展示了 SKILL.md 强调的两点原则在真实数据中的落地:主指标命名了真实表面(pagination_virtualized_vs_table_ratio而非泛化的benchmark_seconds),且 correctness 命令直指 Playwright 集成测试里具体的原生行为用例。
超大文档 legacy 对比——react-huge-document-legacy-compare的完整命令展示了环境变量的典型形态:
REACT_HUGE_COMPARE_LEGACY_REPO=../../../slate \ REACT_HUGE_COMPARE_DISPOSE_DELAY_MS=0 \ REACT_HUGE_COMPARE_SPLIT_SELECTION=1 \ REACT_HUGE_COMPARE_ISOLATE_SURFACES=1 \ REACT_HUGE_COMPARE_SURFACES=v2DefaultRenderAuto,v2DomPresent \ REACT_HUGE_COMPARE_BLOCKS=5000 \ REACT_HUGE_COMPARE_ITERATIONS=5 \ REACT_HUGE_COMPARE_TYPE_OPS=10 \ bun run bench:react:huge-document:legacy-compare:local其主指标为react_huge_doc_legacy_compare_worst_p95_ratio(5,000 块下 v2 默认渲染/DOM-present 两条产品 lane 相对 legacy chunking-on 的最差 p95 比值),promotion 阈值是<=1.5。注意LEGACY_REPO=../../../slate的写法——这正是 SKILL.md 所说“声称 legacy parity 时对比../slate/../../../slate”的实例。
此外,react-huge-document-virtualized-type-to-paint目标给出了 SKILL.md 契约之外的量化阈值:promotion 为react_huge_doc_type_to_paint_p95_ms < 75,stretch 为< 50;react-huge-document-full的聚合目标则要求react_huge_doc_full_max_budget_ratio <= 1且failure_count = 0,stretch 目标是< 0.67。
五、缺失目标策略:一个具体 id 就是足够指令
SKILL.md 对“目标不在注册表里”的情况给出了明确政策,核心立场是:不要强迫用户写“如果缺失就创建目标”这类长提示词。当<target-id>不在slate-v2.json中、且名称具体到可以推断出性能表面时,应在同一趟工作里直接创建一等目标契约。被认定为“足够具体”的名称示例:
react-huge-document-select-allcore-observation-comparepagination-virtualized-fast-scrollhistory-fragment-undo-redo
创建目标时有一组硬性规则:
- 先加注册表条目,再初始化 Autoresearch 会话;
- 尽量复用或扩展最近的现有基准脚本;只有在没有任何现有命令能诚实暴露该指标时,才创建小型基准 owner;
- 基准从一开始就打印
METRIC行; - 主指标必须命名真实表面,禁止泛化的
benchmark_seconds; - 若声称 legacy parity,则对比
../slate/../../../slate(.tmp/slate-v2相对仓库根的上三级); - 添加覆盖所涉原生编辑器行为的 correctness 命令;
- 初始化 AR 会话前先 dry-run 并跑
pnpm bench:targets:check。
若目标名含糊,正确动作是停下来,推荐一两个具体的 target id——而不是为缺失的基准目标再创建一个slate-ar-*包装技能:slate-ar-perf独占性能目标的 bootstrap 职责。
文档同时明确了迁移期的职责切分:旧的 Slate v2bench:*package scripts 在迁移期间继续拥有“工作负载执行”,而干净的分工是——目标注册表拥有决策契约,基准脚本拥有运行时工作负载,Autoresearch 拥有活动优化状态,目标报告/历史拥有历史状态。policy块在 slate-v2.json 开头也有对应声明(“Benchmark implementation lives with the runtime/package code it measures”等四条)。
六、精确性闸门:性能收益不能以正确性受损为代价
SKILL.md 的 Exactness Gate 一句话立论:Performance wins do not count when the editor is less correct.在执行分页、虚拟化、隐藏 DOM、模型支撑的选区(model-backed selection)或分阶段渲染(staged-render)优化之前,必须:
- 识别出确切的正确性 oracle 或浏览器 proof 命令;
- 若 oracle 不存在,先用
slate-patch或tdd补上; - 在把某类原生行为用作基准队列之前,先将其分类为“保留(preserved)”“有意降级(intentionally degraded)”或“范围外(out of scope)”;
- 冷路径估算只能当脚手架提示用,不能当作权威的布局或选区真相;
- 若一个 packet 提速了但破坏了选区、输入顺序、IME、复制、粘贴、撤销、焦点或后续输入,则记
checks_failed或discard,永不记keep。
这一规则与 slate-ar 的全局原则一致:“Slate correctness beats local metric movement.” 从注册表数据也能验证该闸门的落地方式:多数目标以bun check(快速 Slate v2 检查套件)作为兜底 correctness 命令,而性能关键目标则升级到针对性的 Playwright 用例,例如react-runtime-node-fanout的 correctness 命令直接锁定packages/slate-react下test/provider-hooks-contract.tsx中 “fan out / full-document replacement” 两组用例,并要求slate_react_runtime_node_fanout_count=0才允许 promotion。
七、分页默认契约(Pagination Default Contract)
分页或页级虚拟化工作时,除非用户给出更精确的目标,一律从以下契约起步。
目标路由:
http://localhost:3100/examples/pagination?page_layout=single&strategy=virtualized&rows=800必选队列(cohorts):
| 队列 | 参数 | 策略 |
|---|---|---|
| small | rows=8 | staged 与 virtualized |
| table-large | rows=500 | staged 与 virtualized |
| stress | rows=800或rows=1000 | virtualized |
| table-span | 表格跨至少 10 页 | — |
主指标(越小越好):
- 快速打字突发(fast typing burst)的 p95,或总交互延迟;
- 该路由的初始可交互时间(initial interactive time);
- 从 staged 切换到 virtualized 的策略切换延迟;
- 快速滚动恢复时间(fast scroll recovery time)。
次级指标:
- 丢失或被重排字符数;
- DOM 节点数;
- 已挂载页数(mounted page count);
- 页面 overscan 数;
- 可得时的 React commit 数或 render 数;
- 低成本可得时的堆(heap)估算。
正确性检查(全部为原生浏览器行为):
- 快速打字突发期间无跳过/重排字符;
- 插入换行(insert break)后,后续输入的字符保持在光标之后;
- 点击左边距选中行首;
- 点击右边距选中行尾;
- 双击选中一个单词;
- 拖拽选区在顶部/底部附近能自动滚动;
- 跨可见页面内容的文本选区可用;
- 原生复制/粘贴/全选行为要么保留、要么被显式分类。
基准输出必须打印METRIC行,例如:
METRIC typing_p95_ms=42 METRIC dropped_chars=0 METRIC dom_nodes=1840注册表中的react-pagination-virtualized-char-burst目标(见 4.3 节)即该契约的当前实现形态:主指标pagination_virtualized_vs_table_ratio在同一次运行内对比rows=800虚拟化突发延迟与 staged 500 行表格突发,correctness 侧绑定 4 条 Playwright 用例(staged 级性能包络、换行后模型光标处文本仍为 fast staged、原生双击选中投影分页单词、虚拟化选区落在折行末端)。
八、超大文档全选默认契约(Huge Document Select-All)
对react-huge-document-select-all目标,SKILL.md 规定创建或使用带如下契约的目标。
必选队列:
- 5k 块,对比 legacy Slate;
- Slate v2 主超大文档 React 表面;
- 若分阶段/DOM-present 或虚拟化表面是产品路径,则纳入;
- 原生键盘全选(
Mod+A),而不只是程序化模型选区。
主指标(越小越好):
| 指标 | 含义 |
|---|---|
react_huge_doc_select_all_p95_ms | 全选操作的 p95 延迟 |
react_huge_doc_select_all_worst_p95_ratio | 相对 legacy 的最差 p95 比值 |
react_huge_doc_select_all_failure_count | 失败次数 |
次级指标:全选后的 DOM 节点数;低成本可得时的 React commit 数;可单独观测时的选区导出/导入耗时;低成本可得时的整篇复制延迟。
正确性检查:
Mod+A选中完整编辑文档;- 全选后打字只替换一次所选内容;
- undo 能一致地恢复前一份文档与选区;
- 复制返回所选文档的完整纯文本;
- 在分阶段、部分 DOM 或虚拟化渲染下,大范围选区保持有效;
- 不得依赖隐藏的 debounce 或延迟式正确性。
晋级(promotion)目标:
- 第一关:worst p95 ratio
<= 1.5且失败数为0; - 最终目标:worst p95 ratio
<= 1.0,或连续 3 个正确性全绿 packet 收益小于 5% 且无剩余安全 P0/P1 profiler 假设时进入 plateau。
注意这套阈值与注册表中react-huge-document-legacy-compare的promotion: react_huge_doc_legacy_compare_worst_p95_ratio<=1.5相互呼应,说明技能文档中的“默认契约”与注册表条目中的实际阈值是同一套数字的两个投影。
九、Handoff:性能循环的交付报告
slate-ar-perf结束时(Handoff 节)要求报告以下内容,这与 slate-ar 的 handoff 结构保持同一词汇表:
- 基准命令与主指标;
- baseline、latest 与 best 三个数值;
- kept / discarded / crashed / checks-failed 的 packet 计数;
- 使用的正确性检查;
- 被保留工作所改动的文件;
- dashboard URL(若已起服务);
- 下一个推荐 packet 或阻塞点。
其中 packet 的四态(kept/discarded/crashed/checks-failed)正是 Exactness Gate 的可执行化:正确性失败不会污染“best”序列,而是单独计数并路由给slate-patch。
十、小结:决策契约、工作负载、活动状态与历史状态的四方分离
slate-ar-perf的设计可以压缩为四条不变量:
- 决策可测量:每个性能问题先落到注册表里一条带
question、command、metrics.primary、correctness.command的目标记录,pnpm bench:targets:check保证结构合法; - 指标可解析:基准输出必须打印
METRIC name=value(printsMetric: true的目标已在注册表中标注,其余目标以upgrade字段标记“下次触碰时改用原生 METRIC 行”的升级方向); - 正确性先于速度:keep 判定必须同时满足“主指标改善 + 原生行为 checks 全绿”,否则记
checks_failed/discard; - 停止有客观标准:目标 parity、≤1.5→≤1.0 的晋级阈值、5%/3 连包的 plateau 定义,以及架构阻塞时的
slate-plan移交。
对于希望在自己的编辑器仓库中复刻这一套体系的团队,可直接参考 benchmarks/targets/README.md 的目标契约说明与 tooling/scripts/bench-targets.mjs 中list/check/dry-run/report/autoresearch-init五个子命令的实现,以及 benchmarks/targets/reports/slate-v2.md 展示的报告形态(由pnpm bench:targets:report从注册表与 artifact 汇总生成,不执行昂贵基准)。
【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考