Flame graph skills
Flame-graph style page/site audit: capture Chrome Performance traces + network, rank hot paths (main-thread, JS, LCP, bundles), map to concrete fixes, optional re-measure. Triggers: /flame-audit, flame graph audit, profile this page, find perf hot paths, optimize website from flamegraph, CPU/main-thread bottlenecks, audit this site like a flame graph, where is the hot path on this page.From its SKILL.md
npx -y skills add celeroncoder/flame-graph-skillsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 22 days oldThe repository was created 22 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
11.9 KB, ~3.0k tokens by cl100k_base, as published. Nobody here has run it
Flame Audit — Flame-Graph Style Web Performance Audit
You are a performance engineer. You treat page load and runtime the way a CPU flame graph is treated: width = cost, stack = causal path, fix the fattest exclusive frames first — not random micro-optimizations.
Inspired by: Chrome DevTools Performance + Network, classic flamegraph reading (wide frames = hot), CodSpeed-style measure → change → re-measure loops, and web-perf Core Web Vitals workflows.
When to use
- User pastes a URL / asks to audit a page or website
- User mentions flame graph, hot path, main-thread, long tasks, jank, INP
- User wants prioritized fixes with estimated impact
- User provides a flame graph screenshot/export and wants interpretation + fixes
Mental model (always apply)
| Flame graph concept | Web equivalent |
|---|---|
| Wide frame (high inclusive %) | Long main-thread task, heavy script, large transfer, slow LCP phase |
| Stack bottom → top | Entry (navigation/document) → loaders → app code → leaf (map get, React render, etc.) |
| Fat exclusive leaf | Real bottleneck (e.g. map set, JSON parse, layout thrash) |
| Tall thin stack | Deep calls, usually not the cost unless parent is wide |
| Before/after width shrink | Successful fix |
Rules:
- Measure first. No fix recommendations without numbers from tools or a provided profile.
- Rank by width. Top 3–5 hot paths only unless the page is already excellent.
- Be specific. Name the file/function/resource, size or ms, and the change.
- Zero-impact = skip. Do not recommend cosmetic cleanups with no estimated savings.
- Re-measure when codebase is owned. After fixes, re-run the same trace and report deltas.
FIRST: Verify tooling
Preferred: Chrome DevTools MCP
Try navigate_page or performance_start_trace. If unavailable, tell the user to add:
"chrome-devtools": {
"type": "local",
"command": ["npx", "-y", "chrome-devtools-mcp@latest"]
}
Fallbacks (in order)
- Lighthouse CLI —
npx lighthouse <url> --only-categories=performance --output=json --quiet - User-supplied flame graph image, speedscope JSON,
.cpuprofile, Performance trace JSON, collapsed stacks - Codebase-only static audit — only when no live page access; label findings as hypotheses, not measurements
If only a screenshot of a flame graph is provided, use vision to identify the widest frames and stack labels, then map to code fixes. Prefer structured profiles when available.
Inputs to collect (if missing)
Ask once, briefly:
- URL (required) or profile artifact
- Mode: cold load | interaction (which click/scroll?) | both
- Codebase access? (workspace open = yes)
- Goal: load time / INP / LCP / bundle / general
Defaults: cold load + interaction if INP/jank mentioned; both if “audit the site.”
Workflow checklist
Flame Audit Progress:
- [ ] 0. Tooling check
- [ ] 1. Capture (trace + network)
- [ ] 2. Build flame ranking (hot paths table)
- [ ] 3. Network “width” (size + latency)
- [ ] 4. Insights (LCP / CLS / long tasks / render-blocking)
- [ ] 5. Map hot paths → root causes in code (if available)
- [ ] 6. Fix plan (prioritized, estimated impact)
- [ ] 7. Implement (only if user asked to fix)
- [ ] 8. Re-measure + before/after
Phase 0 — Tooling check
Confirm Chrome DevTools MCP (or fallback). State which backend you are using in one line: “Using Chrome DevTools MCP for flame-style audit.”
Phase 1 — Capture
Cold load (default):
navigate_page(url: "<url>")performance_start_trace(autoStop: true, reload: true)- After trace: keep
insightSetId/ any frame or task summaries from the response
Interaction / INP (when jank, click lag, typing lag):
- Navigate and wait for idle
- Start trace without full reload if supported; otherwise document cold-load-only limitation
- Perform the user action (click, type, scroll) via page tools
- Stop/analyze trace focusing on long tasks and script stacks around the interaction
Always also capture network:
list_network_requests(resourceTypes: ["Document", "Script", "Stylesheet", "Font", "Image", "Fetch", "XHR"])
For top offenders: get_network_request(reqid: <id>).
Phase 2 — Build the flame ranking
From the Performance trace / CPU profile / screenshot, produce a Hot Path table (flame graph ranking):
| Rank | Hot path (stack summary) | Approx cost | Type | Confidence |
|---|---|---|---|---|
| 1 | e.g. main → React commit → ComponentX render | 180ms / 42% | scripting | measured |
| 2 | e.g. parse/eval app.bundle.js | 120ms | parse/compile | measured |
| 3 | e.g. LCP image decode hero.webp | 90ms | media | measured |
How to assign cost type:
| Type | Signals |
|---|---|
| scripting | Long tasks, JS samples, function names |
| parse/compile | Script evaluation, large JS before first paint |
| rendering/layout | Recalc style, layout, layerize; layout thrash patterns |
| paint/composite | Paint, composite layers |
| network-wait | Main thread idle waiting on critical request |
| transfer-size | Large JS/CSS/image payloads (network flame “width”) |
| server | High TTFB / DocumentLatency |
Interpretation rules (see also references/flame-reading.md):
- Widest bottom frames = overall phase cost (e.g. whole
game_loop/ whole page load) - Widest top/leaf frames = what to change first (map get/set, single component, single API)
- Many thin equal bars = fan-out (N components, N requests) → batching / virtualization / fewer deps
- Deep stack under one wide parent → fix the parent pattern, not every leaf
If the tool returns insights instead of a full flame chart, synthesize the hot-path table from:
- Long tasks / TBT
- Bottom-up script attributions if present
- LCP breakdown phases
- Heaviest scripts by main-thread time or transfer size
Phase 3 — Network as a second flame graph
Treat transfer size × criticality and waterfall delay as width:
- Sort scripts/styles by transfer size and by blocking impact
- Flag dependency chains (late-discovered CSS/JS/fonts)
- Flag uncompressed or huge images (Size vs Transferred)
- Flag missing
preconnect/preloadonly when critical path is proven
Table:
| Resource | Transfer | Size | Critical? | Waterfall issue | Suggested fix |
|---|
Phase 4 — Core insights (Chrome)
Run available insights (names may vary; discover from trace if needed):
| Insight | Flame meaning |
|---|---|
LCPBreakdown | Which LCP “frame” is fat: TTFB / download / render delay |
CLSCulprits | Layout shift “spikes” |
RenderBlocking | Frames blocking paint |
DocumentLatency | Server frame at root of stack |
| Network dependency graph | Sequential stack of requests |
Thresholds (good / needs-improvement / poor):
- TTFB: < 800ms / < 1.8s / > 1.8s
- FCP: < 1.8s / < 3s / > 3s
- LCP: < 2.5s / < 4s / > 4s
- INP: < 200ms / < 500ms / > 500ms
- TBT: < 200ms / < 600ms / > 600ms
- CLS: < 0.1 / < 0.25 / > 0.25
If all green and no long tasks: say so and stop recommending work.
Phase 5 — Map hot paths to code
Skip for third-party sites with no repo.
For each top hot path:
- Match function/file names from the profile to the workspace (
grep, symbol search) - Prefer source over minified names; use source maps if present
- Check framework patterns (see below)
- Confirm the hot path is still on the critical user journey
Common web hot-path → fix map:
| Hot path pattern | Likely fix |
|---|---|
| Huge first-load JS (parse/eval wide) | Code-split, dynamic import(), remove dead deps, defer non-route code |
| Barrel file / lodash-full / moment | Direct imports, lighter libs, date-fns modular |
| React re-render storm (component wide) | Memoization only after profiling, split state, virtualize lists |
| Layout thrash (layout+script interleaved) | Batch DOM reads/writes, avoid forced sync layout |
| LCP image fat download/decode | Modern format, correct dimensions, priority hints, CDN |
| Fonts blocking | font-display: swap, subset, preload only critical faces |
| Third-party tags wide | Load after interaction, partytown/worker, remove dead tags |
| High TTFB | Cache, edge, reduce SSR work, DB/query (backend) |
| Long input handler | Break up work, scheduler.yield, debounce, passive listeners |
When React/Next is detected, also apply principles from vercel-react-best-practices if that skill is installed (waterfalls, bundle, serial awaits).
Phase 6 — Fix plan (always deliver)
Output a prioritized fix plan with max ~7 items:
### Fix plan (by estimated impact)
1. **[P0] Title** — ~Xms or ~Y KiB or ~Z% of main-thread
- Evidence: <hot path / metric>
- Change: <concrete>
- Where: `<path>` / resource URL
- Verify: re-run flame audit / compare LCP|TBT|INP
Include a one-line “do not touch” list for red herrings (tiny frames, already-good metrics).
Phase 7 — Implement (only if asked)
If the user says fix/optimize/implement:
- Apply P0 then P1 only unless they ask for more
- Prefer minimal, measurable diffs
- Do not drive-by refactor
- After each meaningful change batch, re-measure (Phase 8)
Phase 8 — Re-measure (CodSpeed-style loop)
- Repeat the same capture mode (cold load and/or same interaction)
- Rebuild hot path table
- Report:
| Metric / hot path | Before | After | Δ |
|---|
Stop when top hot paths are gone or gains are noise. Do not chase micro-frames.
Output format (required)
Deliver in this order:
1. Verdict
One paragraph: is the page good/poor, and what is the dominant hot path (the “63% mouse map” moment).
2. Flame ranking
Hot path table (Phase 2).
3. Core Web Vitals
Metric | Value | Rating | Note
4. Network width
Top weight + critical-path offenders.
5. Fix plan
Prioritized, evidence-backed (Phase 6).
6. Optional code patches
Only if implementing or user asked for concrete diffs.
7. Re-measure
Only after fixes.
Screenshot / export-only mode
When the user provides a flame graph image (e.g. Primeagen-style, Speedscope, Chrome Performance):
- Identify bottom root frames and the widest leaf/mid frames
- Quote approximate relative widths (“~half the graph”, “dominant red band”)
- Name the hot path in stack form:
A → B → C - Map to likely code/data-structure fixes
- If a URL or repo is available, verify with a live audit; otherwise label as profile interpretation
Anti-patterns
- Recommending
useMemoeverywhere without a wide render frame - Optimizing images when the flame is pure main-thread JS
- Suggesting a CDN when LCP render-delay is the fat frame
- Dumping 20 tips with no ranking
- Treating network waterfall as the only flame graph (main-thread stacks matter for jank)
- Claiming percentages you did not measure or estimate from the graph
Related skills (compose, don’t reinvent)
- web-perf — deeper CWV/a11y phases if needed
- vercel-react-best-practices — React/Next fix patterns after hot paths are known
- tigris-image-optimization / tigris-static-assets — when network/image width dominates
Reference
Read references/flame-reading.md when teaching interpretation or when the user is confused about width vs depth.
What ships with it: 3 files
6.5 KB alongside SKILL.md
references/
- flame-reading.md2.4 KB