performance · diff

git:20261025.debe22c to git:20261025.6dc09bd

78 added, 19 removed. Audit A to A.

---
name: performance
description: Performance profiling and optimization skill. Audits Core Web Vitals (LCP, CLS, INP), N+1 queries, bundle budgets, and memory leaks.
---
# Performance Profiling & Optimization (`/performance`)
- > **Philosophy**: *Measure with evidence, not intuition. Eliminate N+1 query cascades, bound memory allocations, and enforce strict Core Web Vitals budgets.*
+ > **Philosophy**: *Measure with evidence, not intuition. Eliminate N+1 query cascades, bound memory allocations, and enforce strict Core Web Vitals budgets. If it is not measured, it will degrade.*
- This skill establishes performance optimization standards across frontend client bundles, API latency budgets, and database query executions.
+ This skill establishes performance optimization standards across frontend client bundles, Core Web Vitals, API latency budgets, memory leaks, and database query executions.
---
## 1. Performance Guardrails & Budgets
```mermaid
- flowchart LR
- A["Frontend Bundle (< 250KB Gzip)"] --> B["Core Web Vitals (LCP < 2.5s, CLS < 0.1)"]
- B --> C["API Latency (p95 < 200ms)"]
- C --> D["Database Queries (Zero N+1, Indexed Joins)"]
- D --> E["Cache Layer (In-memory LRU / Redis)"]
+ flowchart TD
+ subgraph FrontendBudgets["1. Frontend & Client Budgets"]
+ A["Core Web Vitals: LCP < 2.5s, CLS < 0.1, INP < 200ms"]
+ B["Initial JS Bundle Budget: < 150KB Gzip"]
+ C["Aspect-Ratio Reservation on All Media"]
+ end
+ subgraph NetworkBudgets["2. Network & Caching"]
+ D["API p95 Latency < 200ms"]
+ E["Bounded LRU Caches with TTL & Eviction"]
+ F["Immutable Cache Headers on Static Assets"]
+ end
+ subgraph DataBudgets["3. Datastore & Execution"]
+ G["Zero N+1 Query Cascades (Batch / Join Fetch)"]
+ H["Connection Pool Sizing <= 2 * CPU Cores"]
+ I["Zero Unbounded Loops in Event Handlers"]
+ end
+ FrontendBudgets --> NetworkBudgets --> DataBudgets
```
- ### Budget 1: Core Web Vitals (CWV)
- - **Largest Contentful Paint (LCP)**: Under `2.5s`. Optimize hero images (`priority`, `fetchpriority="high"`), inline critical CSS.
- - **Cumulative Layout Shift (CLS)**: Under `0.1`. Always declare explicit `width` and `height` (or aspect ratio) on images, videos, and embedded iframes.
- - **Interaction to Next Paint (INP)**: Under `200ms`. Offload heavy compute tasks to Web Workers or chunk work using `scheduler.yield()`.
+ ---
- ### Budget 2: Database Query & N+1 Prevention
- - **Strict Rule**: Never execute database queries inside iterative loops (`for item in items: db.query(...)`).
- - **Standard**: Batch loads using `WHERE id IN (...)` or eager relationship loading (`include: { profile: true }`, `joinedload(User.profile)`).
+ ## 2. Core Web Vitals (CWV) Optimization Guide
- ### Budget 3: Asset Caching & Bundle Size
- - Chunk client bundles dynamically using dynamic imports (`React.lazy()`, Next.js `dynamic()`).
- - Serve immutable static assets with: `Cache-Control: public, max-age=31536000, immutable`.
+ | Metric | Target Budget | Optimization Strategies | Failure Anti-Pattern |
+ | :--- | :--- | :--- | :--- |
+ | **LCP (Largest Contentful Paint)** | `< 2.5s` | Preload hero image (`fetchpriority="high"`), inline critical CSS, server-side render text content | Lazy-loading the hero image (`loading="lazy"` on above-the-fold content) |
+ | **CLS (Cumulative Layout Shift)** | `< 0.1` | Explicit `width` and `height` or `aspect-ratio: 16/9`, reserved skeleton blocks for ads/banners | Dynamic insertion of content above existing content without reserved space |
+ | **INP (Interaction to Next Paint)** | `< 200ms` | Debounce inputs (200-300ms), break long tasks via `scheduler.yield()`, move heavy compute to Web Workers | Synchronous regex or sorting of 10,000 items on main thread |
---
- ## 2. Performance Budget Auditor CLI
+ ## 3. JavaScript Memory Safety & Leak Prevention
- Scan your repository for bundle size violations and N+1 query patterns:
+ Avoid the 3 most common Node.js / React memory leaks:
+ 1. **Unbounded Global Maps / Caches**:
+ ```typescript
+ // ❌ LEAK: Map grows indefinitely until OOM crash
+ const cache = new Map();
+
+ // ✅ PRODUCTION: LRU cache with strict entry cap
+ import { LRUCache } from "lru-cache";
+ const cache = new LRUCache({ max: 500, ttl: 1000 * 60 * 5 }); // 5 minutes TTL
+ ```
+ 2. **Dangling Event Listeners**:
+ ```typescript
+ // Always remove listeners in cleanup function
+ useEffect(() => {
+ const handler = () => handleResize();
+ window.addEventListener("resize", handler);
+ return () => window.removeEventListener("resize", handler);
+ }, []);
+ ```
+ 3. **Uncleared Timers / Intervals**:
+ Store timer references and clear them in component unmount or error handlers.
+
+ ---
+
+ ## 4. Input Debouncing & Rate Limiting
+
+ Never trigger network requests on every raw keystroke. Debounce input changes:
+
+ ```typescript
+ export function useDebounce<T>(value: T, delayMs: number = 300): T {
+ const [debounced, setDebounced] = useState<T>(value);
+
+ useEffect(() => {
+ const timer = setTimeout(() => setDebounced(value), delayMs);
+ return () => clearTimeout(timer);
+ }, [value, delayMs]);
+
+ return debounced;
+ }
+ ```
+
+ ---
+
+ ## 5. Performance Budget Auditor CLI
+
+ Scan your repository for bundle size violations, missing media dimensions, and N+1 query patterns:
```bash
python3 skills/performance/scripts/audit_performance_budgets.py --path .
```
+ Audits:
+ - Presence of explicit dimensions or aspect ratios on image/video tags.
+ - Nested loop database queries in backend controllers.
+ - Unbounded in-memory collections without eviction policies.
+ - Client bundles exceeding size budgets.