How to fix slow LCP (over 4 seconds)
Slow LCP — the big visible element taking more than 4 seconds to render — is the single most common Core Web Vitals failure. The fix almost always comes from 4–5 specific patterns applied in order.
Run through these in order; each one is cheaper than the next.
1. Identify the LCP element
Before you fix anything, know what the LCP element is. PageSpeed Insights tells you in its diagnostic panel: "Largest Contentful Paint element — <img src="/hero.jpg">". Or a specific <h1>, or a <div> with a CSS background.
Most of the time it's an image. Sometimes it's a large text block held up by a font.
2. If the LCP is an image, optimize it
Use modern formats. AVIF is ~50% smaller than JPEG at the same quality. WebP is ~30% smaller. Convert once at build time with sharp or a CDN.
Size it correctly. Don't serve a 2400px-wide hero for a 800px phone viewport. Use <img srcset> or Next.js <Image> to serve the right size per device.
Add explicit width and height. Prevents CLS and lets the browser allocate space immediately.
Preload it. Add <link rel="preload" as="image" href="/hero.jpg" fetchpriority="high"> in <head>, or use fetchpriority="high" on the <img> itself. This tells the browser "fetch this before anything else."
Put it behind a fast CDN. Vercel Image, Cloudflare Images, Imgix, whatever. Just not your origin.
3. If the LCP is text, fix fonts
Text can't paint until the font is ready. If your hero headline is in a custom web font that takes 1.5 seconds to arrive, your LCP is at least 1.5 seconds no matter what.
font-display: swap(oroptionalfor stricter control) — renders in fallback immediately, swaps when custom arrives<link rel="preload" as="font" crossorigin>for the critical font file- Subset fonts to only the characters you need — a Latin subset is usually 30% the size of full
- Self-host instead of Google Fonts if latency is regional
4. Fix render-blocking resources
Render-blocking CSS and JS block first paint. First paint blocks LCP.
- Inline critical CSS in
<head>(the ~10KB needed for above-the-fold) - Defer non-critical CSS:
<link rel="stylesheet" media="print" onload="this.media='all'">pattern - Defer or async all
<script>tags — never<script src="…">without a modifier in<head>
5. Reduce TTFB
If your server takes 2 seconds to respond, LCP cannot be under 2 seconds. Read the TTFB guide for the full story, but the short version: cache, CDN, edge.
6. Move to the edge
If the above doesn't close the gap, the next step is rendering at the edge:
- Next.js: switch hot pages to
export const runtime = 'edge'or ISR - Cloudflare Pages / Workers
- Vercel Edge Network
Edge gives you single-digit-millisecond TTFB for cached content, which cascades to LCP under 1 second for most pages.
Sanity check
After fixes, re-run PageSpeed Insights. If LCP is still >2.5s, the LCP element is probably a different element now — re-identify and repeat.
By Paulo de Vries · Published