$npx -y skills add addyosmani/agent-skills --skill performance-optimizationOptimizes application performance across frontend, backend, queries, and databases. Use when performance requirements exist, when you suspect performance regressions, when Core Web Vitals or load times need improvement, when N+1 query patterns need fixing, or when profiling revea
| 1 | # Performance Optimization |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | Measure before optimizing. Performance work without measurement is guessing — and guessing leads to premature optimization that adds complexity without improving what matters. Profile first, identify the actual bottleneck, fix it, measure again. Optimize only what measurements prove matters. |
| 6 | |
| 7 | ## When to Use |
| 8 | |
| 9 | - Performance requirements exist in the spec (load time budgets, response time SLAs) |
| 10 | - Users or monitoring report slow behavior |
| 11 | - Core Web Vitals scores are below thresholds |
| 12 | - You suspect a change introduced a regression |
| 13 | - Building features that handle large datasets or high traffic |
| 14 | |
| 15 | **When NOT to use:** Don't optimize before you have evidence of a problem. Premature optimization adds complexity that costs more than the performance it gains. |
| 16 | |
| 17 | ## Core Web Vitals Targets |
| 18 | |
| 19 | | Metric | Good | Needs Improvement | Poor | |
| 20 | |--------|------|-------------------|------| |
| 21 | | **LCP** (Largest Contentful Paint) | ≤ 2.5s | ≤ 4.0s | > 4.0s | |
| 22 | | **INP** (Interaction to Next Paint) | ≤ 200ms | ≤ 500ms | > 500ms | |
| 23 | | **CLS** (Cumulative Layout Shift) | ≤ 0.1 | ≤ 0.25 | > 0.25 | |
| 24 | |
| 25 | ## The Optimization Workflow |
| 26 | |
| 27 | ``` |
| 28 | 1. MEASURE → Establish baseline with real data |
| 29 | 2. IDENTIFY → Find the actual bottleneck (not assumed) |
| 30 | 3. FIX → Address the specific bottleneck |
| 31 | 4. VERIFY → Measure again, confirm improvement |
| 32 | 5. GUARD → Add monitoring or tests to prevent regression |
| 33 | ``` |
| 34 | |
| 35 | ### Step 1: Measure |
| 36 | |
| 37 | Two complementary approaches — use both: |
| 38 | |
| 39 | - **Synthetic (Lighthouse, DevTools Performance tab):** Controlled conditions, reproducible. Best for CI regression detection and isolating specific issues. |
| 40 | - **RUM (web-vitals library, CrUX):** Real user data in real conditions. Required to validate that a fix actually improved user experience. |
| 41 | |
| 42 | **Frontend:** |
| 43 | ```bash |
| 44 | # Synthetic: Lighthouse in Chrome DevTools (or CI) |
| 45 | # Chrome DevTools → Performance tab → Record |
| 46 | # Chrome DevTools MCP → Performance trace |
| 47 | |
| 48 | # RUM: Web Vitals library in code |
| 49 | import { onLCP, onINP, onCLS } from 'web-vitals'; |
| 50 | |
| 51 | onLCP(console.log); |
| 52 | onINP(console.log); |
| 53 | onCLS(console.log); |
| 54 | ``` |
| 55 | |
| 56 | **Backend:** |
| 57 | ```bash |
| 58 | # Response time logging |
| 59 | # Application Performance Monitoring (APM) |
| 60 | # Database query logging with timing |
| 61 | |
| 62 | # Simple timing |
| 63 | console.time('db-query'); |
| 64 | const result = await db.query(...); |
| 65 | console.timeEnd('db-query'); |
| 66 | ``` |
| 67 | |
| 68 | ### Where to Start Measuring |
| 69 | |
| 70 | Use the symptom to decide what to measure first: |
| 71 | |
| 72 | ``` |
| 73 | What is slow? |
| 74 | ├── First page load |
| 75 | │ ├── Large bundle? --> Measure bundle size, check code splitting |
| 76 | │ ├── Slow server response? --> Measure TTFB in DevTools Network waterfall |
| 77 | │ │ ├── DNS long? --> Add dns-prefetch / preconnect for known origins |
| 78 | │ │ ├── TCP/TLS long? --> Enable HTTP/2, check edge deployment, keep-alive |
| 79 | │ │ └── Waiting (server) long? --> Profile backend, check queries and caching |
| 80 | │ └── Render-blocking resources? --> Check network waterfall for CSS/JS blocking |
| 81 | ├── Interaction feels sluggish |
| 82 | │ ├── UI freezes on click? --> Profile main thread, look for long tasks (>50ms) |
| 83 | │ ├── Form input lag? --> Check re-renders, controlled component overhead |
| 84 | │ └── Animation jank? --> Check layout thrashing, forced reflows |
| 85 | ├── Page after navigation |
| 86 | │ ├── Data loading? --> Measure API response times, check for waterfalls |
| 87 | │ └── Client rendering? --> Profile component render time, check for N+1 fetches |
| 88 | └── Backend / API |
| 89 | ├── Single endpoint slow? --> Profile database queries, check indexes |
| 90 | ├── All endpoints slow? --> Check connection pool, memory, CPU |
| 91 | └── Intermittent slowness? --> Check for lock contention, GC pauses, external deps |
| 92 | ``` |
| 93 | |
| 94 | ### Step 2: Identify the Bottleneck |
| 95 | |
| 96 | Common bottlenecks by category: |
| 97 | |
| 98 | **Frontend:** |
| 99 | |
| 100 | | Symptom | Likely Cause | Investigation | |
| 101 | |---------|-------------|---------------| |
| 102 | | Slow LCP | Large images, render-blocking resources, slow server | Check network waterfall, image sizes | |
| 103 | | High CLS | Images without dimensions, late-loading content, font shifts | Check layout shift attribution | |
| 104 | | Poor INP | Heavy JavaScript on main thread, large DOM updates | Check long tasks in Performance trace | |
| 105 | | Slow initial load | Large bundle, many network requests | Check bundle size, code splitting | |
| 106 | |
| 107 | **Backend:** |
| 108 | |
| 109 | | Symptom | Likely Cause | Investigation | |
| 110 | |---------|-------------|---------------| |
| 111 | | Slow API responses | N+1 queries, missing indexes, unoptimized queries | Check database query log | |
| 112 | | Memory growth | Leaked references, unbounded caches, large payloads | Heap snapshot analysis | |
| 113 | | CPU spikes | Synchronous heavy computation, regex backtracking | CPU profiling | |
| 114 | | High latency | Missing caching, redundant computation, network hops | Trace request |