Web Performance
Measure and optimize load time, interactivity, and visual stability - targeting Core Web Vitals (LCP, INP, CLS) to improve UX and search rankings.
skill: Web Performance category: Web Development tags: [Web Performance, Core Web Vitals, LCP, CLS, Lighthouse] readingTime: 7
Web performance is not a nice-to-have - Core Web Vitals directly affect Google Search rankings and every 100ms of delay costs measurable conversion. Measure first (Lighthouse, CrUX, real user monitoring), then fix the biggest bottleneck. Premature micro-optimization is wasted effort.
Workflow
- Measure baseline with Lighthouse and CrUXLab data (Lighthouse) tells you what's fixable; field data (CrUX) tells you what real users experience. Fix field data issues first.
- Optimize LCP (Largest Contentful Paint)LCP measures when the main content is visible - slow LCP is usually a large unoptimized image or render-blocking resources.
- Eliminate CLS (Cumulative Layout Shift)CLS measures unexpected layout shifts - caused by images without dimensions, late-loading fonts, or dynamic content injected above existing content.
- Reduce JS with code splittingA large JS bundle blocks parsing. Code splitting sends only the JS needed for the current route - the rest is loaded on demand.
- Cache assets aggressivelyA returning visitor should never re-download unchanged assets. Content-addressed filenames (hash in filename) enable permanent caching.
Output Format
Performance-optimized site hitting Core Web Vitals thresholds: LCP < 2.5s, INP < 200ms, CLS < 0.1.
LCP: preloaded hero image in AVIF/WebP, CDN delivery
INP: deferred non-critical JS, no long tasks on main thread
CLS: explicit dimensions on all media, reserved slots for ads
TTFB: CDN edge caching, server response time < 200ms
FID: < 100ms (replaced by INP in 2024)Examples
Input
Output
Input
Output
Edge Cases & Gotchas
- Lighthouse score ≠ real user experience - Lighthouse runs in a controlled lab environment. Always corroborate with CrUX field data - a 90 Lighthouse score can coexist with poor real-world LCP if your server is slow.
- Third-party scripts kill INP - Analytics, chat widgets, and ad scripts run on the main thread and cause long tasks. Load them with `async`/`defer` and `loading='lazy'` where possible.
- Font subsetting - Loading a full variable font (2MB) for a single language is wasteful. Subset with `glyphs` parameter in Google Fonts or use pyftsubset locally.
- SSR doesn't guarantee fast LCP - Server-side rendering sends HTML faster, but if the server is slow or TTFB is high (>600ms), LCP still suffers. Optimize server response time first.
When to Break These Rules
- Don't optimize prematurely - measure before each fix and confirm improvement in field data (CrUX), not just Lighthouse scores.
- Don't sacrifice correctness for speed - if caching causes stale critical data (prices, stock), reduce cache TTL rather than eliminating it.
Reference Files
https://web.dev/performance/https://developer.chrome.com/docs/crux/