When you change something on the interactive path (typing, completion, scrolling, opening files, indexing, search), run them before and after the change and include the numbers in the PR’s verification section.
UI: pnpm perf
perf/run.ts builds the workbench with vite build --mode perf (the production bundle plus the sample project and a __openideaPerf probe), serves it, drives interaction scenarios in Chromium with Playwright, and checks the medians of the measured runs.
--warmup <n> (default 1), --headed, --no-build (reuse the last build), --channel <browser> (default chromium, or OPENIDEA_PERF_CHANNEL), --fail-on-regression.
Scenarios (perf/scenarios.ts): typing, typingLarge, typingAngular, completion, consoleOutput, terminalTui, keyRepeat, scroll, gitLog, gitLogScrollbar, resizePanels, startup, tabs, agentTabs, popups, toolWindows, projectTree, leaks. Bundle size (bundle.initialJsKb, bundle.initialCssKb) is checked on every run.
Latencies are measured from input to the start of the first frame that shows the result, so about 16.7 ms means “next frame”.
This runs in Chromium, while the desktop app runs in the system webview (WebKit on macOS and Linux, WebView2 on
Windows). It catches regressions in the frontend’s own work reliably; absolute numbers in the app can differ.
Adding a scenario
A scenario inperf/scenarios.ts has an id, a title and a run(h) that drives the page through the harness (perf/lib/harness.ts: open files, set the cursor, type and measure, read editor state) and returns metrics. Add a budget for each metric you want enforced as "<scenario>.<metric>" in budgets.json.
Backend: pnpm perf:rust
perf/rust.ts runs cargo bench for ide-text, ide-language, ide-index, ide-search and ide-host, reads the Criterion results from target/criterion, and checks each bench’s mean (in µs).
crates/<crate>/benches/:
Budgets and baselines
perf/budgets.json holds upper bounds (lower is better):
ui:<scenario>.<metric>→ bound, compared with the median of the measured runs; enforced at CPU 1x only;rust: Criterion bench id → mean in microseconds;regressionTolerance(0.2) andregressionFloor(1): how much worse than the baseline a metric may get, relative and absolute, before it counts as regressed.
Baselines are local (
target/perf/), so save one on your machine before you start changing things, and compare on the same machine.
Comparing with other IDEs: perf/compare
pnpm perf measures OpenIDEA from inside its webview. perf/compare/bench.py measures any IDE from the outside, the same way for each, so OpenIDEA can be compared with the other apps listed in perf/compare/apps.toml:
results/<time>-<project>/ (report.md, results.json).
Use release builds only; the script refuses to run while another instance of the same executable is running. See perf/compare/README.md for fair-run rules and platform notes.