Fix Prioritize LCP Image for Better LCP

How to prioritize your LCP image with fetchpriority and preload to eliminate resource load delay and improve Core Web Vitals.
Harlan WiltonHarlan Wilton6 min read Published

Only 15% of sites use fetchpriority="high" on their LCP image—up from 0.03% in 2022. The other 85% leave performance on the table.

What's the Problem?

When browsers load a page, they prioritize resources based on type and position. Images start with low priority by default. Your hero image—the most important visual element—competes with analytics scripts, third-party widgets, and other low-priority requests.

The browser doesn't know which image is your LCP element until it calculates layout. By then, precious milliseconds are wasted. The "Prioritize LCP image" audit fires when Lighthouse detects your LCP image could have loaded faster with explicit prioritization.

This audit specifically checks two things: whether the LCP image has fetchpriority="high" applied, and whether the image is discoverable in the initial HTML (not loaded via JavaScript or CSS).

How to Identify This Issue

Chrome DevTools

  1. Open DevTools (F12) → Performance tab
  2. Record a page load
  3. Find your LCP marker in the timeline
  4. Look at the Network section—when did the LCP image request start?
  5. If there's a gap between HTML arrival and image request, prioritization helps

Lighthouse

Look for: "Prioritize LCP image" in the Opportunities section. The audit shows:

  • Which image is your LCP element
  • Whether fetchpriority is applied
  • Whether the image is discoverable from HTML

Quick Check

View page source. Search for your hero image. Check:

  • Does it have fetchpriority="high"?
  • Is the URL in the HTML, or set by JavaScript/CSS?

The Fix

Primary Solution: Add fetchpriority="high"

The simplest fix. Tell the browser this image matters.

<!-- Before: browser guesses priority -->
<img src="hero.webp" alt="Hero image">

<!-- After: explicit high priority -->
<img src="hero.webp" fetchpriority="high" alt="Hero image">

This single attribute can reduce LCP by 100-400ms on typical pages.

Secondary Solution: Preload the LCP Image

When the image URL isn't immediately discoverable (e.g., set by CSS background), preload it.

<head>
  <link
    rel="preload"
    href="/images/hero.webp"
    as="image"
    fetchpriority="high"
  >
</head>

For responsive images with srcset:

<link
  rel="preload"
  as="image"
  href="/images/hero.webp"
  imagesrcset="
    /images/hero-400.webp 400w,
    /images/hero-800.webp 800w,
    /images/hero-1200.webp 1200w
  "
  imagesizes="100vw"
  fetchpriority="high"
>

Make the Image Discoverable

Move LCP images from CSS/JavaScript to HTML.

<!-- Before: image URL hidden in CSS (not discoverable) -->
<div class="hero" style="background-image: url(hero.webp)"></div>

<!-- After: image in HTML (immediately discoverable) -->
<img src="hero.webp" class="hero-img" fetchpriority="high" alt="Hero">
// Before: image URL set after component mounts
const [heroSrc, setHeroSrc] = useState(null)
useEffect(() => {
  setHeroSrc('/hero.webp')
}, [])

// After: image URL known at render time
<img src="/hero.webp" fetchPriority="high" alt="Hero" />

Complete Example

<head>
  <!-- Preload for earliest possible discovery -->
  <link
    rel="preload"
    href="/images/hero.webp"
    as="image"
    fetchpriority="high"
    imagesrcset="
      /images/hero-400.webp 400w,
      /images/hero-800.webp 800w
    "
    imagesizes="100vw"
  >
</head>
<body>
  <img
    src="/images/hero.webp"
    srcset="
      /images/hero-400.webp 400w,
      /images/hero-800.webp 800w
    "
    sizes="100vw"
    fetchpriority="high"
    loading="eager"
    decoding="async"
    width="1200"
    height="600"
    alt="Descriptive alt text"
  >
</body>

Why This Works

The browser's resource scheduler assigns priority to each request. By default:

  • Scripts: High
  • Stylesheets: Highest
  • Images in viewport: Low → Medium (after layout)
  • Images outside viewport: Low

fetchpriority="high" overrides this. The browser:

  1. Sees the image immediately in HTML
  2. Knows it's high priority before layout calculation
  3. Starts downloading sooner, potentially in parallel with critical CSS

Preload goes further—it starts the request during HTML parsing, before the browser even reaches the <img> tag.

The combination of discoverable HTML + fetchpriority + preload can eliminate 500ms+ of resource load delay.

Framework-Specific Solutions

Next.jsUse the priority prop on next/image. This adds both fetchpriority and preload automatically:
import Image from 'next/image'

// priority adds fetchpriority="high" and preloads the image
<Image
  src="/hero.jpg"
  width={1200}
  height={600}
  priority
  alt="Hero"
/>
Only use priority on above-the-fold images—typically just the LCP image.
NuxtUse preload prop on NuxtImg to generate a preload link:
<NuxtImg
  src="/hero.jpg"
  width="1200"
  height="600"
  preload
  alt="Hero"
/>
For manual control with useHead:
useHead({
  link: [{
    rel: 'preload',
    href: '/images/hero.webp',
    as: 'image',
    fetchpriority: 'high'
  }]
})
ReactAdd fetchPriority (camelCase in JSX) directly to your img:
<img
  src="/hero.webp"
  fetchPriority="high"
  loading="eager"
  alt="Hero"
/>
For preload, add to your HTML head or use a head management library like react-helmet.

Verify the Fix

After implementing:

  1. Network tab — Filter by "Img". LCP image should show "High" in Priority column
  2. Elements tab — Check that fetchpriority="high" is present on the LCP image
  3. Performance tab — Record and verify the LCP image request starts earlier
  4. Lighthouse — The "Prioritize LCP image" audit should pass

Expected improvement: 100-500ms reduction in LCP, depending on page complexity and network conditions.

Common Mistakes

Preloading the Wrong Image

Preload hints are powerful but wasteful if used incorrectly.

<!-- Wrong: preloading a below-fold image -->
<link rel="preload" href="/product-gallery.webp" as="image">

<!-- Right: only preload the actual LCP image -->
<link rel="preload" href="/hero.webp" as="image" fetchpriority="high">

Too Many High-Priority Images

If everything is high priority, nothing is.

<!-- Wrong: multiple high-priority images -->
<img src="hero.webp" fetchpriority="high" alt="">
<img src="logo.webp" fetchpriority="high" alt="">
<img src="banner.webp" fetchpriority="high" alt="">

<!-- Right: only the LCP image gets high priority -->
<img src="hero.webp" fetchpriority="high" alt="">
<img src="logo.webp" alt="">
<img src="banner.webp" alt="">

Preload with Incorrect Attributes

Missing or wrong attributes cause double downloads.

<!-- Wrong: missing 'as' attribute -->
<link rel="preload" href="/hero.webp">

<!-- Wrong: mismatched srcset -->
<link rel="preload" as="image" imagesrcset="hero-800.webp 800w">
<img srcset="hero-400.webp 400w, hero-800.webp 800w"> <!-- Different srcset! -->

<!-- Right: matching attributes -->
<link rel="preload" as="image"
  imagesrcset="hero-400.webp 400w, hero-800.webp 800w"
  imagesizes="100vw">
<img srcset="hero-400.webp 400w, hero-800.webp 800w" sizes="100vw">

Dynamic LCP Images Without Server-Side Logic

If your LCP image varies per page, you need server-side rendering to set the correct preload.

<!-- Wrong: hardcoded preload on dynamic pages -->
<link rel="preload" href="/default-hero.webp" as="image">
<!-- But this page's LCP is actually /product-42-hero.webp -->

<!-- Right: dynamic preload matching actual LCP -->
<link rel="preload" href="/product-42-hero.webp" as="image">

Often appears alongside:

Test Your Entire Site

Different pages have different LCP elements. Your homepage might use a hero image while product pages use product photos. Unlighthouse scans your entire site and identifies which pages are missing LCP image prioritization.