Performance advice without a trace is speculation, and AI is a fluent speculator. This module closes the loop: agents that record real browser traces via chrome-devtools-mcp, extract LCP/INP/CLS insights, apply fixes, and re-trace to prove the metric moved — plus AI-ranked triage for bundles, re-renders, production errors, and upgrade loops.
Aditya owns web performance at a grocery-delivery product. The product detail page: LCP 4.8s on mid-range Android, INP failing, conversion sliding. Mandate: pass Core Web Vitals by quarter end.
He asks an assistant for "ways to improve LCP on a React product page." Twelve confident suggestions arrive: memoize, lazy-load, preload, code-split, CDN, SSR…
He implements three. LCP moves from 4.8s to 4.7s. The suggestions weren't wrong — they were generic. Nothing in the loop had ever observed his page.
He wires chrome-devtools-mcp. The agent records a real trace on a throttled profile. The insights are specific: LCP element is the hero image — loaded via CSS background, invisible to the preload scanner; 1.9s render-delay from a font-blocking chain; an INP trap in the quantity stepper re-rendering the entire cart tree.
Fix one cause, re-trace, compare. Hero to <img fetchpriority="high">: LCP 4.8 → 3.1. Font display: swap + preconnect: 3.1 → 2.4. Stepper state scoped: INP passes.
CWV green in field data. Every fix has a before/after trace attached to its PR. Nobody argued with the PRs.
The first two days are the cautionary half of the story: an LLM asked about performance in the abstract returns the statistical average of every performance blog post ever written — plausible, generic, and unmoored from your page. The quarter-saving half is the pattern this module teaches: give the AI eyes, then close the loop. With chrome-devtools-mcp, the model stops advising from memory and starts reasoning from your trace — and the re-trace after each fix converts opinion into evidence. The same loop-closure discipline extends to everything in the performance-and-debugging workload: bundle analysis, INP forensics, production error triage, cross-browser reproduction, and framework upgrades with deterministic harnesses.
chrome-devtools-mcp gives a coding agent a real Chrome instance: navigate, emulate CPU/network throttling, record a performance trace (performance_start_trace), and read back the trace's extracted insights — LCP breakdown by phase, long tasks, layout shifts with their culprits, render-blocking requests. The workflow that follows is the module's backbone, and each step has a failure mode the discipline exists to prevent:
What the loop's evidence looks like in practice — Aditya's first cycle, as the agent reported it:
background-image — invisible to the preload scanner, discovered at style-recalcfont-display: auto, no preconnect)Fix one cause, re-trace under identical conditions, attach both traces to the PR.
Lab 08 ships an app with three seeded pathologies — unsplit bundle, unoptimized hero, an INP trap — and passes only on before/after traces clearing stated thresholds. Claims without traces fail the lab, which is precisely the standard your PRs should hold.
The unit of performance work is not the fix — it is the trace-fix-retrace cycle. Any workflow that ends at "applied the optimization" has shipped a hypothesis with a commit message.
Bundle bloat is artifact-interpretation work, which is a genuine model strength — when the artifact is provided. Feed real stats output (source-map-explorer, rollup-plugin-visualizer, webpack stats JSON) to the model and ask for a ranked reduction plan with expected savings per item:
import() boundaries from the module graph.export * chains that drag whole directories into every chunk; tedious to trace by hand, mechanical for the model.Then the discipline: verify each claim by building and measuring, top-ranked first. Model estimates of savings are directionally useful and numerically unreliable — the bundle diff is the scoreboard. Stop when marginal items cost more review than they save bytes.
INP failures are where frontend performance gets React-shaped (or framework-shaped generally): the trace shows a long task after an interaction; why the task is long lives in profiler artifacts. The workflow pairs them — hand the model the DevTools long-task flame chart and the React Profiler's commit data ("what rendered and why") for the same interaction, and have it name the pathology from the recognizable taxonomy:
memo decorative.useTransition, deferral, or moving work off the interaction path.The model is good at naming the pattern from the artifacts and proposing the standard fix; you confirm by re-profiling the same interaction. Same loop, smaller scale.
When the model proposes memoization, make it also identify which reference instability currently defeats it — memo without stabilized inputs is a no-op that reviews as an optimization. If it can't name the unstable input from the profiler data, the diagnosis isn't grounded yet.
On-call debugging is multi-artifact correlation under time pressure — exactly the shape AI accelerates safely, because the output is a ranked hypothesis list you verify, not a fix you deploy blind. Web-side: feed the source-mapped Sentry stack, breadcrumbs, release diff, and affected-session characteristics (browser, device, geography, release) to the model; ask for ranked hypotheses each with the evidence that would confirm or kill it, plus a user-impact estimate to calibrate urgency. Mobile-side (M8 goes deeper): App Quality Insights with Gemini analysis or symbolicated Crashlytics stacks, segmented by device/OS — the segmentation usually is the clue (one OEM, one OS version, one screen density). In both, the rule from the SWE track holds with frontend teeth: verify the top hypothesis against reality — reproduce with the agent-driven browser, or find the disconfirming breadcrumb — before writing the fix. Fluent wrong hypotheses cost more in production than they cost in review.
"Works in Chrome, broken in Safari" bugs die by isolation, and an agent-driven browser makes isolation cheap: reproduce the defect via Playwright across engines (Chromium/WebKit/Firefox) in one run, confirm it's engine-specific, then have the model — which holds baseline/caniuse-grade compatibility knowledge — hypothesize the specific feature gap or quirk and generate the minimal repro that proves it. The minimal repro is the deliverable: it converts "Safari is weird" into "flex min-height resolves differently inside this grid context, here are 12 lines demonstrating it," which yields a guarded fix (and often a one-line workaround) instead of a superstition. File the repro with the fix PR; future archaeologists will bless you.
Framework and SDK upgrades — Next.js majors, Expo SDKs, React Native via upgrade-helper, Flutter/AGP/targetSdk bumps — are recurring forced work with a known safe shape: an agentic loop inside a deterministic harness. The harness is non-negotiable and defined before the loop starts: typecheck, test suite, build, plus the visual-diff suite from M4 for UI-touching upgrades. The loop: codemods first (framework-official, deterministic), then the agent iterates on the residue — run harness, read failures, fix, repeat — while you review each iteration's diff for semantic drift the harness can't see (changed defaults, behavioral flag flips buried in release notes). The agent reads release notes and migration guides faster than you; the harness keeps its fixes honest; the human owns "this default changed and our product depends on the old one."
| Task | AI's role | The verifier |
|---|---|---|
| CWV repair | Trace analysis, fix proposals | Re-trace, then field data |
| Bundle diet | Ranked plan from stats | Bundle diff per change |
| INP forensics | Pathology naming from profiler artifacts | Re-profile the interaction |
| Error/crash triage | Ranked hypotheses + impact estimate | Reproduction or disconfirming evidence |
| Cross-browser bugs | Quirk hypothesis + minimal repro | Repro runs in the failing engine |
| Upgrades | Iterating residue inside the loop | Typecheck/test/build harness + visual diffs |
Every row of that table has the same trap: the model's explanation arrives before the evidence and reads like a conclusion. The explanation is the hypothesis. The right-hand column is the conclusion. Teams that invert this ship eloquent regressions.
This module's playbooks: pb-34 (Loop-Closed Core Web Vitals Repair with chrome-devtools-mcp), pb-35 (Bundle-Size Investigation), pb-36 (INP and Re-Render Forensics), pb-37 (Loading-Strategy Sweep), pb-38 (Cross-Browser Bug Triage with an Agent-Driven Browser), pb-39 (Source-Mapped Production Error Triage), and pb-40 (Framework and SDK Upgrade Loops). Lab 08 is the loop-closed repair: three seeded pathologies, before/after traces required past thresholds — claims without traces fail, by design.
Give the AI eyes, then close the loop. A model reasoning over your trace, your stats file, your profiler output is a diagnostic force multiplier; the same model without artifacts is a generic blog post. And in either case the metric only counts when the re-trace says it moved.