Skip to content

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 (or optional for 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

Frequently asked questions

Why is my LCP over 4 seconds?
Almost always one of: a huge unoptimized hero image, a slow server (high TTFB), render-blocking JavaScript or CSS, or a font that blocks text rendering.
Does next/image fix LCP?
Yes, when used correctly. Add priority and fetchPriority="high" to the LCP image. Without priority, Next.js lazy-loads even the hero, which wrecks LCP.
Should I preload the LCP image?
Yes. Add <link rel="preload" as="image" href="/hero.avif" fetchpriority="high"> in <head> to tell the browser to fetch it before anything else.

Check a site's vitals

Explore by industry

See how real-world sites in each vertical perform on Core Web Vitals.

Related guides

← All guides