Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Teach agents to use the Chrome DevTools MCP server for performance testing with traces, Core Web Vitals, throttling, and evidence-based analysis.
.claude/skills/pramoddutta-chrome-devtools-mcp-performance/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 12% | 0% |
| case-09 | ✗→✓ | ▲ Improved | -14% | 0% |
| case-12 | ✗→✓ | ▲ Improved | -6% | 0% |
| case-13 | ✗→✓ | ▲ Improved | -10% | 0% |
| case-07 | ✓→✓ | = Same ✓ | 74% | 0% |
You are a web performance engineer who drives Chrome DevTools through an MCP server to capture traces, measure Core Web Vitals, analyze network and CPU bottlenecks, and turn observations into targeted fixes.
Install the MCP server and prepare a local performance target.
bashnpm install --save-dev @playwright/test typescript npm pkg set scripts.perf:serve='vite --host 127.0.0.1' npm pkg set scripts.perf:smoke='tsx scripts/perf-smoke.ts'
Configure your agent to expose Chrome DevTools MCP according to your MCP client.
json{ "mcpServers": { "chrome-devtools": { "command": "npx", "args": ["chrome-devtools-mcp@latest"] } } }
Keep performance evidence and scripts outside normal E2E tests.
textperformance/ traces/ budgets/ web-vitals.json notes/ checkout-lcp.md scripts/ perf-smoke.ts summarize-trace.ts
Use this loop when asked to investigate performance.
Use Playwright to collect browser-side performance entries for quick checks.
typescript// scripts/perf-smoke.ts import { chromium } from '@playwright/test'; const url = process.env.PERF_URL || 'http://127.0.0.1:5173'; const browser = await chromium.launch(); const page = await browser.newPage(); await page.goto(url, { waitUntil: 'networkidle' }); const metrics = await page.evaluate(() => { const nav = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming; const resources = performance.getEntriesByType('resource') as PerformanceResourceTiming[]; return { domContentLoaded: Math.round(nav.domContentLoadedEventEnd - nav.startTime), load: Math.round(nav.loadEventEnd - nav.startTime), transferKb: Math.round(resources.reduce((sum, item) => sum + item.transferSize, 0) / 1024), resourceCount: resources.length, }; }); console.log(JSON.stringify(metrics, null, 2)); await browser.close();
Turn repeated findings into a simple local budget.
typescript// scripts/check-performance-budget.ts type Metrics = { domContentLoaded: number; load: number; transferKb: number; resourceCount: number; }; const budget = { domContentLoaded: 2000, load: 3500, transferKb: 900, resourceCount: 90, }; export function assertBudget(metrics: Metrics): void { const failures = Object.entries(budget).filter(([key, limit]) => { return metrics[key as keyof Metrics] > limit; }); if (failures.length > 0) { throw new Error(`Performance budget failed: ${JSON.stringify(failures)}`); } }
When reviewing a trace, inspect these areas in order.
| Signal | DevTools Evidence | Likely Fix | |---|---|---| | Slow LCP | LCP element and waterfall | Preload image, reduce server time, optimize hero | | High CLS | Layout shift records | Reserve dimensions, avoid late banners | | Poor INP | Long tasks near input | Split JavaScript and reduce handler work | | High TTFB | Navigation timing | Cache, optimize backend, use edge | | Large JS | Coverage and network | Code split and remove unused libraries | | Slow fonts | Waterfall and rendering | Preload, swap, subset fonts |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-07 | pass→pass | 12,051 | 16,473 | +37% | 1 | 1 | 0% | 1,730 | 3,018 | +74% | 0 | 0 | — |
case-19 | pass→pass | 16,697 | 16,735 | +0% | 1 | 1 | 0% | 1,773 | 3,319 | +87% | 0 | 0 | — |
case-17 | pass→pass | 10,065 | 4,529 | -55% | 1 | 1 | 0% | 1,249 | 2,190 | +75% | 0 | 0 | — |
case-18 | pass→pass | 7,713 | 10,474 | +36% | 1 | 1 | 0% | 1,310 | 2,957 | +126% | 0 | 0 | — |
case-01 | fail→fail | 19,001 | 21,795 | +15% | 1 | 1 | 0% | 512 | 2,021 | +295% | 0 | 0 | — |
case-02 | fail→fail | 19,787 | 17,978 | -9% | 1 | 1 | 0% | 190 | 1,815 | +855% | 0 | 0 | — |
case-03 | fail→fail | 14,662 | 14,394 | -2% | 1 | 1 | 0% | 397 | 1,867 | +370% | 0 | 0 | — |
case-04 | fail→pass | 18,739 | 10,074 | -46% | 1 | 1 | 0% | 1,930 | 2,166 | +12% | 0 | 0 | — |
case-05 | pass→pass | 12,325 | 9,034 | -27% | 1 | 1 | 0% | 894 | 2,072 | +132% | 0 | 0 | — |
case-06 | fail→fail | 17,934 | 12,853 | -28% | 1 | 1 | 0% | 2,243 | 3,547 | +58% | 0 | 0 | — |
case-08 | pass→pass | 9,675 | 5,423 | -44% | 1 | 1 | 0% | 630 | 2,283 | +262% | 0 | 0 | — |
case-09 | fail→pass | 19,912 | 9,070 | -54% | 1 | 1 | 0% | 2,380 | 2,035 | -14% | 0 | 0 | — |
case-10 | pass→pass | 11,152 | 8,403 | -25% | 1 | 1 | 0% | 969 | 1,979 | +104% | 0 | 0 | — |
case-11 | fail→fail | 16,377 | 7,672 | -53% | 1 | 1 | 0% | 1,742 | 1,835 | +5% | 0 | 0 | — |
case-12 | fail→pass | 13,120 | 8,154 | -38% | 1 | 1 | 0% | 2,008 | 1,896 | -6% | 0 | 0 | — |
case-13 | fail→pass | 13,437 | 7,974 | -41% | 1 | 1 | 0% | 2,108 | 1,895 | -10% | 0 | 0 | — |
case-14 | pass→pass | 11,991 | 4,763 | -60% | 1 | 1 | 0% | 945 | 2,183 | +131% | 0 | 0 | — |
case-15 | pass→pass | 16,405 | 12,355 | -25% | 1 | 1 | 0% | 1,487 | 2,580 | +74% | 0 | 0 | — |
case-16 | pass→pass | 19,987 | 11,207 | -44% | 1 | 1 | 0% | 1,898 | 3,026 | +59% | 0 | 0 | — |
case-20 | pass→pass | 21,894 | 15,712 | -28% | 1 | 1 | 0% | 2,963 | 4,075 | +38% | 0 | 0 | — |
case-21 | fail→fail | 27,555 | 22,645 | -18% | 1 | 1 | 0% | 4,752 | 4,721 | -1% | 0 | 0 | — |
case-22 | fail→fail | 16,670 | 9,799 | -41% | 1 | 1 | 0% | 1,980 | 3,180 | +61% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 19 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +18 percentage points is the difference between those two pass rates over the 19 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.