改动交互路径(输入、补全、滚动、打开文件、索引、搜索)时,在改动前后各跑一次,并把数字写进 PR 的验证说明。
UI:pnpm perf
perf/run.ts 用 vite build --mode perf 构建工作台(生产包 + 示例项目 + __openideaPerf 探针),起一个静态服务,用 Playwright 在 Chromium 中驱动交互场景,并检查多次测量的中位数。
--warmup <n>(默认 1)、--headed、--no-build(复用上次构建)、--channel <browser>(默认 chromium,或 OPENIDEA_PERF_CHANNEL)、--fail-on-regression。
场景(perf/scenarios.ts):typing、typingLarge、typingAngular、completion、consoleOutput、terminalTui、keyRepeat、scroll、gitLog、gitLogScrollbar、resizePanels、startup、tabs、agentTabs、popups、toolWindows、projectTree、leaks。每次运行都会检查包体积(bundle.initialJsKb、bundle.initialCssKb)。
延迟是从输入到显示结果的第一帧开始的时间,因此约 16.7 ms 就表示“下一帧”。
测量在 Chromium 里进行,而桌面应用运行在系统 webview 中(macOS 和 Linux 上是 WebKit,Windows 上是
WebView2)。它能可靠地发现前端自身工作的退化,但应用里的绝对数值可能不同。
新增场景
perf/scenarios.ts 中的场景包含 id、title 和 run(h):通过 harness(perf/lib/harness.ts:打开文件、设置光标、输入并测量、读取编辑器状态)驱动页面并返回指标。需要强制检查的指标,在 budgets.json 中以 "<scenario>.<metric>" 加上预算。
后端:pnpm perf:rust
perf/rust.ts 对 ide-text、ide-language、ide-index、ide-search 和 ide-host 运行 cargo bench,从 target/criterion 读取 Criterion 结果,检查每个基准的平均值(µs)。
crates/<crate>/benches/:
预算与基线
perf/budgets.json 保存上限(越低越好):
ui:<scenario>.<metric>→ 上限,与多次测量的中位数比较;只在 CPU 1x 时强制检查;rust:Criterion 基准 id → 平均值(微秒);regressionTolerance(0.2)和regressionFloor(1):指标比基线差多少(相对和绝对)才算退化。
基线保存在本地(
target/perf/),所以开始改动前先在自己的机器上存一份基线,并在同一台机器上对比。
与其他 IDE 对比:perf/compare
pnpm perf 是在 OpenIDEA 的 webview 内部测量。perf/compare/bench.py 则从外部、用同样的方式测量任意 IDE,以便把 OpenIDEA 与 perf/compare/apps.toml 中列出的其他应用做对比:
results/<time>-<project>/(report.md、results.json)。
只使用 release 构建;同一可执行文件已有实例在运行时脚本会拒绝执行。公平测量的规则和各平台说明见 perf/compare/README.md。