Perf Triage
A Claude Code skill for triaging runtime performance problems in a running web app — 100% CPU, jank, a freeze, a slow tab/route switch — by capturing a real CPU profile over the Chrome DevTools Protocol (CDP) and diagnosing from it, instead of guessing from source.
It encodes a repeatable workflow and the hard-won decision lessons from real perf investigations: which metric matches which symptom, how to capture a profile when the DevTools panel crashes on huge traces, and how to fix with measure-and-revert discipline.
Why CDP instead of the DevTools panel
A long, high-CPU spike produces a huge trace, and the DevTools Performance panel crashes rendering the flame chart. CDP's Profiler domain hands back a compact .cpuprofile with no UI involved, so capture always works. The bundled scripts automate this.
What it does
1. Set up a target — launch a separate CDP-enabled Chrome, have you log in and reach the pre-interaction state, hand back the URL. 2. Capture a CPU profile over CDP, driving the interaction itself (deterministic, short window). 3. Analyze offline — idle %, active CPU, per-function self-time, spike shape — picking the metric that matches the symptom. 4. Diagnose the mechanism (accidental O(N²), event/notification storm, an expensive cache guard). 5. Fix with discipline — smallest behavior-preserving change, re-measure each one, revert anything that doesn't help.
Install
/plugin marketplace add iamsaumya/perf-triage
/plugin install perf-triage@perf-triage
Then invoke it on an issue:
/perf-triage:perf-triage
To try it locally without installing:
claude --plugin-dir /path/to/perf-triage
Requirements
- A Chromium-based browser (Chrome / Edge / Brave) launchable with
--remote-debugging-port. - Node 21+ (built-in
WebSocket/fetch), or Node 18–20 with thewspackage (npm i ws) for the capture script. - The web app running and reachable.
The bundled tooling
skills/perf-triage/scripts/capture-cpuprofile.js— connect to Chrome on a debug port, reload, drive a click interaction (by button text), record a.cpuprofile.
node capture-cpuprofile.js --url <appUrl> --trigger "<button text>" [--reset "<other tab>"] [--seconds 22] [--out spike.cpuprofile] [--port 9222]
skills/perf-triage/scripts/capture-scroll.js— capture while an in-page rAF loop drives a scroll (the generic trigger for scroll jank / 100% CPU).
node capture-scroll.js [--url <appUrl>] [--ready "<js expr>"] [--selector "<css>"] [--seconds 20] [--out scroll.cpuprofile] [--port 9222]
skills/perf-triage/scripts/parse-cpuprofile.js— offline analysis of one profile (idle %, active CPU, self/inclusive time, active-CPU-per-second spike shape).
node parse-cpuprofile.js <file.cpuprofile> [topN]
skills/perf-triage/scripts/diff-cpuprofile.js— A/B two profiles by % of active CPU + the absolute active-CPU headline (the honest before/after metric).
node diff-cpuprofile.js <before.cpuprofile> <after.cpuprofile> [topN]
All are generic — parameterized by URL, interaction target, duration, and port. No app-, company-, or framework-specific assumptions. The capture scripts need the ws npm package resolvable from the script's directory (npm i ws); the built-in Node WebSocket silently drops multi-MB profile transfers.
License
MIT — see LICENSE.











