Developer pack
Claude SkillUpdated today

Performance Optimization Workflow

Runs performance work as a measured loop: baseline, find the real bottleneck, fix one thing, re-measure, and revert anything inside the noise.

What it does

Applies a five-step protocol to slow pages and slow APIs: measure a baseline, map the symptom to the actual bottleneck, fix that one thing, re-measure with identical methodology, and add a CI budget so the win survives. Covers Core Web Vitals targets, the standard backend killers (N+1 queries, unbounded fetches, missing caching), and the discipline most performance work skips: reverting changes that do not beat run-to-run variance.

When to use

  • A page or endpoint is slow and nobody has profiled it yet
  • Core Web Vitals fell out of the "Good" band and you need a prioritized route back
  • Reviewing an optimization PR and deciding whether the claimed win is real or inside the noise

When not to use

  • No measured evidence of a problem exists; premature optimization adds complexity that costs more than it returns
  • The issue is specifically React render behavior — react-performance-reviewer carries the framework-level rule set

Install

Download the .zip, then unzip into your Claude skills folder.

mkdir -p ~/.claude/skills
unzip ~/Downloads/performance-optimization-workflow.zip -d ~/.claude/skills/

# Restart Claude Code session.
# Skill is now available — Claude will use it when relevant.

SKILL.md

SKILL.md
---
name: performance-optimization-workflow
description: Use when a page or API is slow, Core Web Vitals need improvement, an N+1 query pattern is suspected, or an optimization claim needs verification. Triggers on "why is this slow", "improve LCP", "this endpoint takes seconds", "did this optimization actually work".
---

# Performance Optimization Workflow

Measure before optimizing; performance work without measurement is guessing. Every engagement runs the same loop — Measure, Identify, Fix, Verify, Guard — and the loop only moves forward on evidence.

## 1. Measure a baseline

Two kinds of measurement, and both matter. Synthetic (Lighthouse, the DevTools Performance panel) is reproducible and belongs in CI. Real-user monitoring (the web-vitals library, CrUX) tells you whether actual users on actual networks got faster, which is the only definition of success that counts. On the backend, response-time logging and query timing fill the same role. Record the baseline numbers and the exact methodology; the verify step reuses both.

Reference targets for the web vitals:

| Metric | Good | Needs improvement | Poor |
| --- | --- | --- | --- |
| LCP | up to 2.5s | up to 4.0s | over 4.0s |
| INP | up to 200ms | up to 500ms | over 500ms |
| CLS | up to 0.1 | up to 0.25 | over 0.25 |

## 2. Map the symptom to the bottleneck

Slow LCP points at large images or render-blocking resources. High CLS points at images without dimensions or content that loads late and pushes the page around. Poor INP points at heavy main-thread JavaScript. On the backend: a slow list endpoint is an N+1 query or a missing index until proven otherwise; steady memory growth is a leaked reference or an unbounded cache; CPU spikes are synchronous heavy computation. Profile to confirm — the assumed bottleneck and the actual one disagree often enough to make guessing expensive.

## 3. Fix exactly one thing

The recurring offenders, in rough order of payoff: N+1 queries (replace the loop with a join or an include), unbounded fetches (paginate with a sane limit), unoptimized images (dimensions set, lazy-loaded below the fold, fetchpriority high on the LCP image), oversized bundles (dynamic imports and route-level code splitting), and missing caching (TTLs on frequently-read rarely-changed data, Cache-Control on static assets and API responses). One change at a time — bundle three fixes and you cannot attribute the result to any of them.

## 4. Verify: keep or revert

Re-measure with the same tools, conditions, and methodology as the baseline. Then apply the decision table without negotiation:

| Result vs. baseline | Action |
| --- | --- |
| Beats the threshold, tests green | Keep; commit with the before and after numbers |
| Within run-to-run variance | Revert |
| Worse | Revert |
| Faster, but a test now fails | Revert; that is a regression wearing a disguise |

Neutral is a revert, not a keep — unmeasured complexity accumulates forever. A 3% gain inside 5% variance is not a gain. Log every attempt including the reverted ones, so the next person does not re-try a failed idea with fresh confidence.

## 5. Guard the win

A fix without a guard decays. Set budgets and enforce them in CI with Lighthouse CI or a bundle-size check: initial JavaScript under 200KB gzipped, CSS under 50KB, above-the-fold images under 200KB each, API p95 under 200ms, Lighthouse performance score at or above 90. Adjust the numbers to the product; the point is that a regression fails a build instead of waiting for a user complaint.

## Red flags

- Optimization proposed without profiling data behind it
- A list endpoint with no pagination
- Images without dimensions or lazy loading
- Liberal React.memo and useMemo sprinkled as a reflex rather than from a profile
- A claimed win that required changing or deleting tests
- Multiple optimizations in one PR, making attribution impossible
- A "fix" kept because it felt faster, with no before and after numbers

Example prompts

Once installed, try these prompts in Claude:

  • Our dashboard endpoint takes 4 seconds. Walk me through finding the bottleneck before we touch any code.
  • Mobile LCP is 4.2s. Give me the measured path back under 2.5s, in priority order.
  • Review this optimization PR: did it beat the baseline, or is the improvement inside run-to-run variance?
Recent changes
  • Aug 4, 2026New skill: the measure/identify/fix/verify/guard loop with Core Web Vitals targets, N+1 and caching anti-patterns, and CI performance budgets.