Page speed is one of the few SEO levers where Google has explicitly told you what to optimize: Core Web Vitals. But CWV is the symptom, not the cause. The 80/20 wins below are the actual work that moves LCP, INP, and CLS, without rebuilding your stack.
1. Fix your TTFB first
Time To First Byte is the floor for everything else. If TTFB is 800 ms, your LCP can never be under 800 ms. Three causes account for 90% of slow TTFB:
- Cold serverless functions. Use a min-instance / warm pool, or move the hot path to a regular long-running server.
- Origin too far from users. Put a CDN in front (Cloudflare, Bunny, Fastly), even the free tiers cache HTML.
- Database round-trips on every render. Cache rendered HTML for anonymous traffic; you can usually serve 95% of pageviews from a 60-second cache.
Target: TTFB < 200 ms at the 75th percentile. Measure in PageSpeed Insights or Cloudflare Web Analytics.
2. Serve images in modern formats
WebP saves 25โ35% over JPEG; AVIF saves another 20% on top of WebP. Most CDNs do this transparently if you turn it on:
- Cloudflare Polish / Image Resizing
- Vercel / Netlify image components
- Bunny Optimizer
If you're hand-rolling, ship <picture> with sources:
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="..." width="1200" height="630">
</picture>
Always include width and height attributes -
they prevent CLS by reserving layout space before the image loads.
3. Stop render-blocking resources
Every <script> in the head without defer
or async blocks parsing. Every blocking
<link rel="stylesheet"> blocks paint. Two rules:
- Inline the critical CSS used above the fold (โค 14 KB).
- Add
deferto every script that doesn't need to run before DOMContentLoaded. Marketing pixels, analytics, chat widgets, all defer.
4. Cache aggressively at the edge
Static assets should have a 1-year Cache-Control with
content-hashed filenames:
Cache-Control: public, max-age=31536000, immutable
HTML can be cached for short windows (10โ60s for anonymous users) plus
stale-while-revalidate for instant subsequent loads:
Cache-Control: public, max-age=10, s-maxage=60, stale-while-revalidate=86400
5. Lazy-load what's below the fold
Add loading="lazy" to every <img> and
<iframe> outside the initial viewport. The browser will
defer download until the user scrolls near them. Native, no JS.
6. Fix font loading
Custom web fonts cause invisible text and layout shift. Fix in two lines:
- Add
font-display: swap;to every@font-faceso text renders in the fallback while the web font loads. - Self-host fonts (don't use Google Fonts CDN, it adds DNS + connection overhead). Subset to only the characters you actually use.
7. Audit and re-measure
Run AuditAI or PageSpeed Insights on your top five landing pages, fix the three highest-impact issues each, then re-measure. Don't optimize blind, most "performance audits" miss the actual bottleneck. Cross-reference with our technical SEO checklist to make sure speed work doesn't break crawl budget or indexing.
The 80/20: CDN + WebP/AVIF + defer scripts +
loading="lazy" + font-display swap. Five interventions account
for almost every page-speed gain we see in the wild.