# Frontend Performance — Derived Rules > Derives from `domains/performance/first-principles.md` P1 (Measure First), P9 (Perceived Performance). ## Measure First (P1) - Lighthouse, Core Web Vitals (LCP, FID/INP, CLS), RUM (Real User Monitoring). - A performance claim without a measurement is an opinion. - Measure the 75th percentile (P75), not the average. The average hides the long tail. ## The Three Core Web Vitals | Vital | What | Target (P75) | |-------|------|--------------| | LCP (Largest Contentful Paint) | When the main content loads | ≤ 2.5s | | INP (Interaction to Next Paint) | When input is responded to | ≤ 200ms | | CLS (Cumulative Layout Shift) | Visual stability | ≤ 0.1 | - LCP > 4s is poor. INP > 500ms is poor. CLS > 0.25 is poor. - Measure on mobile, not just desktop. Mobile is the long tail. ## Perceived Performance (P9) - A skeleton screen beats a spinner. A spinner beats nothing. - Optimistic UI updates: the click responds immediately; the server confirms later. - Prefetch the next page on hover (if cheap). Prefetch is a bet, not a certainty. ## Bundle Size (P4 Resource Bounds, core C8 Economy) - Ship less JavaScript. Every KB is parsed, compiled, and executed on the client. - Code-split routes. Lazy-load below-the-fold. Don't ship the admin bundle to the user bundle. - A 500KB JS bundle is large. A 2MB JS bundle is a defect. ## Images (P4, P6 Lazy by Default) - WebP/AVIF, not JPEG/PNG. Modern formats are 30–50% smaller. - `loading="lazy"` on below-the-fold images. `width`/`height` to prevent CLS. - `srcset` for responsive images. Ship the right size to the right device. - Never ship a 4K image to a 360px screen. ## Rendering (P7 Async When Independent) - Server-render the first paint (SSR/SSG). Hydrate after. - Avoid hydration waterfalls: a 3-second hydration is a 3-second blank page with a "loaded" script. - Defer non-critical hydration. Interactive above the fold first; below the fold later. ## What Violates Frontend Performance | Violation | Principle | |-----------|-----------| | 3MB JS bundle | P4, C8 | | LCP > 4s on mobile | P1 (measured) | | Layout shift on image load | CLS | | Synchronous hydration of a 50KB page | P7 | | No image optimization | P4 |