Skip to main content
CodeRocket
Performancecriticalweb-vitals

Optimize largest contentful paint

rule · largest-contentful-paint

Largest Contentful Paint is the best single metric for whether the page feels ready. A good score usually depends on getting one important element discovered, transferred, and rendered without delay.

Code Examples

Discover the LCP Resource Early

HTML
<head>
  <link
    rel="preload"
    href="/hero.webp"
    as="image"
    type="image/webp"
    fetchpriority="high"
  >
</head>
TSX
import Image from 'next/image'
 
function Hero() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero image"
      width={1200}
      height={600}
      priority
      sizes="100vw"
    />
  )
}

Avoid Client-Rendered LCP Delays

TSX
// Bad: no LCP candidate until client fetch completes
function BadPage() {
  const [data, setData] = useState(null)
 
  useEffect(() => {
    fetch('/api/hero').then((response) => response.json()).then(setData)
  }, [])
 
  if (!data) return null
  return <img src={data.heroImage} alt="Hero" />
}
 
// Better: route renders the LCP content from the server
async function GoodPage() {
  const data = await getHeroData()
 
  return (
    <Image
      src={data.heroImage}
      alt="Hero"
      priority
      width={1200}
      height={600}
    />
  )
}

Text LCP Needs Fast Fonts and Minimal Blocking CSS

TSX
import { Inter } from 'next/font/google'
 
const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
  preload: true,
})

Why It Matters

LCP is the most important Core Web Vital for perceived load speed—it measures when the main content becomes visible, directly impacting user perception and SEO rankings.

LCP Score Thresholds

ScoreRatingUser perception
<= 2.5sGoodThe page feels ready quickly
2.5s-4sNeeds improvementThe main content arrives late
> 4sPoorThe page feels slow

Common LCP Candidates

  • Hero image
  • Hero heading or text block
  • Video poster
  • Large background image

Troubleshooting Flow

When LCP is slow, identify the LCP element first and then classify the delay:

  1. Slow TTFB: the HTML itself arrives late.
  2. Late discovery: the browser does not learn about the LCP resource early enough.
  3. Heavy transfer: the image, font, or CSS is simply too large.
  4. Render delay: the asset arrives, but CSS, JavaScript, or client rendering prevents paint.
  5. Incorrect prioritization: the LCP candidate is lazy-loaded or competing with too many other "important" assets.

Common Causes and Fixes

CauseFix
Slow HTML responsecache more aggressively, reduce origin work, use edge delivery where appropriate
Late-discovered hero mediapreload the current-route LCP asset and avoid lazy loading
Oversized images or postersserve responsive formats and sizes, compress appropriately
Background-image LCPpreload the image and avoid burying discovery behind non-critical CSS
Client-side rendering delaysrender the LCP candidate on the server where possible
Too many competing prioritiesavoid over-preloading fonts, scripts, and secondary images

Anti-Patterns

  • Lazy-loading the LCP candidate
  • Preloading the wrong asset variant
  • Marking multiple images fetchpriority="high"
  • Rendering the hero only after client-side fetches or hydration
  • Hiding the LCP candidate behind heavy CSS or blocking JavaScript

Verification

Start with PageSpeed Insights (opens in a new tab) or a field trace to identify the real LCP candidate, because the wrong fix is easy to apply when the largest element is not the one you expected.

Automated Checks

  • Run Lighthouse or PageSpeed Insights and confirm Largest Contentful Paint <= 2.5s on the target route.
  • Use the Performance panel or web-vitals instrumentation to identify the actual LCP element and confirm it matches your expectation.
  • Inspect the waterfall and confirm the LCP resource is discovered early, requested with the right priority, and not lazy-loaded.

Manual Checks

  • Re-test on a throttled mobile profile after each fix so you can tell whether the bottleneck was TTFB, discovery, transfer, or render delay.
  • If the LCP candidate is text, verify fonts and critical CSS do not delay paint; if it is media, verify bytes and sizing are appropriate.