Page speed is the rare optimization that improves both ranking and revenue simultaneously. Google uses Core Web Vitals as a ranking signal, but the larger commercial benefit is what speed does to conversion — every 100ms of LCP improvement correlates with measurable lifts across industries, and the conversion gains usually dwarf the SEO gains. This playbook covers the full performance stack: network optimizations, server response, rendering, JavaScript, fonts, images, and third-party scripts. The goal is not just to pass Core Web Vitals — it is to build a site that feels instant.
Network Layer Optimizations
Before the browser can render anything, packets must travel from your server to the user and back. Network optimizations cut that round-trip time and the bytes that have to travel.
Enable HTTP/2 or HTTP/3
HTTP/3 (over QUIC) is supported by all modern browsers and most CDNs in 2026. It eliminates head-of-line blocking, uses 0-RTT connection resumption for return visitors, and handles packet loss gracefully on mobile networks. Most CDNs enable HTTP/3 with a single toggle. Verify with curl -I --http3 https://yourdomain.com or your CDN's diagnostics.
Use a CDN
A content delivery network caches your static assets at edge locations close to your users. Cloudflare and Bunny.net offer generous free or low-cost tiers; Fastly and Cloudfront handle enterprise scale. The TTFB improvement for distant users is typically 200-500ms, which directly improves LCP and overall responsiveness.
Compress responses
Enable Brotli compression at the CDN or server level (Brotli compresses 15-25% better than gzip for text-based content). Compress every text response: HTML, CSS, JavaScript, JSON, SVG, web fonts. Most CDNs handle this automatically.
Resource hints
Use <link rel="preconnect"> for critical third-party origins (analytics, fonts, CDN) so the browser establishes the connection early. Use <link rel="preload"> for the LCP image and critical fonts. Avoid <link rel="prefetch"> for resources the user is unlikely to need — it wastes bandwidth and competes with critical work.
Server Response Optimization
Time to First Byte (TTFB) is the floor for LCP — your page can never render faster than your server can respond. Target TTFB under 600ms.
Cache at every layer
Static assets cached at the CDN with long max-age. Database query results cached in Redis or Memcached. Computed pages cached as static HTML where possible. Page caching at the edge for content that does not personalize (homepages, category pages, blog posts) eliminates most server work entirely.
Database query optimization
Slow database queries are a leading TTFB cause. Identify and index slow queries. Avoid N+1 query patterns in ORMs. Cache query results aggressively. Move expensive analytics queries to background jobs that pre-compute summaries.
Right-size your hosting
Underprovisioned hosting throttles TTFB during traffic spikes. Cheap shared hosting often has 1000-3000ms TTFB; modern serverless (Cloudflare Workers, Vercel Edge) or right-sized VMs (DigitalOcean, Hetzner) deliver 50-300ms TTFB. The hosting bill is usually the smallest line item in a serious performance investment.
Rendering Path Optimization
Even with a fast server and CDN, render-blocking resources can stall the page. The browser must download, parse, and execute CSS and JavaScript before it can paint — minimize what blocks rendering.
Inline critical CSS
Inline the CSS required for above-the-fold content directly in the HTML head (under 14KB ideally to fit in the first packet). Load the rest of the stylesheet asynchronously with media="print" onload tricks or modern rel="preload" as="style" patterns. Critical CSS tools like Critical, Penthouse, or framework-native options (Next.js, Nuxt) automate the extraction.
Defer non-critical JavaScript
Add defer or async to any script not needed for first paint. defer waits until HTML parsing completes; async runs as soon as it downloads. Inline only what is absolutely required (typically nothing).
Remove unused CSS and JavaScript
Use Chrome DevTools' Coverage tab to find unused CSS and JS. Tree-shake your build (modern bundlers do this automatically). Remove unused dependencies. Replace large libraries with smaller alternatives (Day.js or date-fns instead of Moment; native fetch instead of axios for simple use cases; individual Lodash imports instead of the whole library).
Image Delivery
Images are typically the largest payload on a page and a leading LCP element. Aggressive image optimization is one of the highest-ROI performance investments.
Modern formats
Serve AVIF (best compression, supported by all major browsers since 2024) or WebP (broader legacy support) with JPEG fallbacks via <picture>. AVIF saves 40-60% over equivalent-quality JPEG; WebP saves 25-35%.
Responsive images
Use srcset and sizes so mobile devices download appropriately small versions. A 4000px wide hero image is wasted on a 400px mobile viewport.
Lazy loading
Add loading="lazy" to images below the fold. Never lazy load the LCP image — that delays the critical paint. Lazy loading is now native in all major browsers.
fetchpriority hints
Set fetchpriority="high" on the LCP image so the browser prioritizes it over other resources. Set fetchpriority="low" on below-the-fold images. The hint is supported in Chrome and Edge; Safari and Firefox treat it as best-effort.
CDN image transformation
Modern CDNs (Cloudflare Images, Cloudinary, Imgix, Shopify CDN, Vercel) transform images on the fly — converting to AVIF/WebP, resizing, compressing — based on URL parameters. Upload one source image; serve infinite optimized variants. Eliminates the build-time image processing burden.
Font Optimization
Web fonts are a common LCP and CLS culprit. Default font loading wastes time and triggers layout shifts when the web font finally loads and characters reflow.
Self-host fonts
Loading from Google Fonts adds DNS lookup, TLS handshake, and round-trip latency to a separate origin. Self-hosting eliminates all three. Tools like google-webfonts-helper generate the self-hostable font files for any Google Font.
font-display: swap
Use font-display: swap in your @font-face declaration. Fallback text appears immediately while the web font loads in the background, then swaps in when ready. Without it, browsers may show invisible text for up to 3 seconds — guaranteed bad LCP.
Preload critical fonts
Preload the one or two fonts used above the fold:
<link rel="preload" as="font" type="font/woff2"
href="/fonts/inter-regular.woff2" crossorigin>
Eliminate font swap shift
Match fallback font metrics to the web font using size-adjust, ascent-override, and descent-override in your @font-face. The Fontaine library generates these declarations automatically. Result: zero layout shift when the web font swaps in.
JavaScript Performance
JavaScript is the leading cause of poor INP and increasingly the dominant performance bottleneck on modern sites. Less JavaScript means a more responsive page.
Code-split aggressively
Ship only what each route needs. Modern frameworks (Next.js, Nuxt, Remix, SvelteKit) code-split routes by default. Audit with source-map-explorer or bundle-analyzer.
Break up long tasks
Any synchronous JavaScript blocking the main thread for more than 50ms is a "long task" that hurts INP. Break work into chunks with setTimeout(fn, 0), requestAnimationFrame, or the newer scheduler.yield() API.
Move heavy work to Web Workers
Parsing large JSON, encryption, image manipulation, large data transformations — anything CPU-bound — belongs in a Web Worker. Comlink makes worker communication ergonomic.
Defer hydration
Modern frameworks support partial hydration (Astro Islands, Qwik resumability, React Server Components) — hydrating only the interactive parts of the page rather than the entire tree. The performance benefit is dramatic on content-heavy pages with isolated interactive widgets.
Third-Party Script Management
Third-party scripts — analytics, A/B testing, chat widgets, ad networks, tag managers — are often the largest INP contributor because you do not control their performance.
Audit relentlessly
List every third-party script. For each one, ask: what does this do, what is its performance cost (load time, main-thread blocking, bytes), is there a lighter alternative, can we defer it until after first interaction? Most sites can remove or defer half their tags without losing functionality.
Load patterns
- async for analytics and tracking scripts that do not affect visible content.
- defer for scripts that need the DOM but do not block rendering.
- Conditionally load chat widgets, A/B testing, and similar tools only after first user interaction.
- Partytown to relocate third-party scripts to a Web Worker so they cannot block the main thread.
Measurement & Monitoring
Performance regresses every release without continuous measurement. Build the monitoring once and check it weekly.
- Chrome DevTools Performance panel for debugging specific issues
- PageSpeed Insights for one-off URL audits with field+lab data
- Search Console Core Web Vitals report for field data trends by URL pattern
- web-vitals library for collecting real-user metrics from your own users
- Lighthouse CI in your build pipeline to catch regressions before deploy
- Performance budgets documented and enforced — every PR that adds 100KB should justify it
The 80/20 of Page Speed
If you have limited time, prioritize:
- Enable HTTP/2 or HTTP/3 and Brotli compression at the CDN (one toggle each)
- Convert and optimize images (AVIF/WebP + responsive + lazy load)
- Preload the LCP image with fetchpriority="high"
- Self-host fonts with font-display: swap and preload
- Defer or async every non-critical script
- Reduce JavaScript bundle size by 30-50% (remove unused code, replace heavy libraries)
- Cache aggressively at the CDN and origin
Done well, these seven items move most sites from "Poor" to "Good" on Core Web Vitals without rewriting a single component.
Compress Your Images for Faster LCP
Drop image files to convert and compress — modern formats and aggressive compression are the highest-ROI speed fix.
Image Compressor →