Optimize web performance for faster loading and better user experience. Use when asked to "speed up my site", "optimize performance", "reduce load time", "fix slow loading", "improve page speed", or "performance audit".
Deep performance optimization based on Lighthouse performance audits. Focuses on loading speed, runtime efficiency, and resource optimization.
How it works
Identify performance bottlenecks in code and assets
Prioritize by impact on Core Web Vitals
Provide specific optimizations with code examples
Measure improvement with before/after metrics
Performance budget
Resource
Budget
Rationale
Total page weight
< 1.5 MB
3G loads in ~4s
JavaScript (compressed)
< 300 KB
Parsing + execution time
CSS (compressed)
< 100 KB
Render blocking
Images (above-fold)
< 500 KB
LCP impact
Fonts
< 100 KB
FOIT/FOUT prevention
Third-party
< 200 KB
Uncontrolled latency
Critical rendering path
Server response
TTFB < 800ms. Time to First Byte should be fast. Use CDN, caching, and efficient backends.
Enable compression. Gzip or Brotli for text assets. Brotli preferred (15-20% smaller).
HTTP/2 or HTTP/3. Multiplexing reduces connection overhead.
Edge caching. Cache HTML at CDN edge when possible.
Send Early Hints (HTTP 103) for slow origins. When the origin needs hundreds of milliseconds to assemble the final response, return a 103 Early Hints with Link: </hero.webp>; rel=preload; as=image (and similar for critical CSS/fonts) so the browser starts fetching before the 200 OK lands. Cloudflare reports 20–30% LCP improvements on image-heavy pages. Requires HTTP/2+ and is supported by Chromium-based browsers; other browsers ignore the 103 and fall through to the 200 — safe to enable. CDNs (Cloudflare, Fastly, Akamai) can synthesize 103s automatically from prior responses; on your own origin, emit them from the same handler that issues the 200.
moderate triggers after a ~200ms hover — usually intent-correlated, rarely wasted. See core-web-vitals → LCP for the full discussion of eagerness tradeoffs and the prerenderingchange gating you'll need for analytics.
// ❌ May cause jank
setInterval(animate, 16);
// ✅ Synced with display refresh
function animate() {
// Animation logic
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
Virtualize long lists
// For lists > 100 items, render only visible items
// Use libraries like react-window, vue-virtual-scroller, or native CSS:
.virtual-list {
content-visibility: auto;
contain-intrinsic-size: 0 50px; /* Estimated item height */
}
Smooth navigations with View Transitions
The View Transitions API lets the browser cross-fade (or custom-animate) between two DOM states using a single GPU-composited snapshot — no double-render, no layout thrash, and the snapshot doesn't count toward CLS.
Same-document (SPA-style) — Baseline 2026:
// Wrap the DOM mutation that swaps the view
function navigate(newView) {
if (!document.startViewTransition) return swapDOM(newView);
document.startViewTransition(() => swapDOM(newView));
}
/* On both source and destination pages */
@view-transition { navigation: auto; }
That's the entire integration — same-origin navigations now fade automatically. To opt specific elements into shared-element transitions (e.g. a thumbnail expanding into a hero), give them a matching view-transition-name: