Fix Prioritize LCP Image for Better LCP
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
- Open DevTools (F12) → Performance tab
- Record a page load
- Find your LCP marker in the timeline
- Look at the Network section—when did the LCP image request start?
- 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:
- Sees the image immediately in HTML
- Knows it's high priority before layout calculation
- 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
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"
/>
priority on above-the-fold images—typically just the LCP image.preload prop on NuxtImg to generate a preload link:<NuxtImg
src="/hero.jpg"
width="1200"
height="600"
preload
alt="Hero"
/>
useHead:useHead({
link: [{
rel: 'preload',
href: '/images/hero.webp',
as: 'image',
fetchpriority: 'high'
}]
})
fetchPriority (camelCase in JSX) directly to your img:<img
src="/hero.webp"
fetchPriority="high"
loading="eager"
alt="Hero"
/>
Verify the Fix
After implementing:
- Network tab — Filter by "Img". LCP image should show "High" in Priority column
- Elements tab — Check that fetchpriority="high" is present on the LCP image
- Performance tab — Record and verify the LCP image request starts earlier
- 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">
Related Issues
Often appears alongside:
- Large Images — Prioritizing a 2MB image still means downloading 2MB
- Lazy-Loading Above Fold — Don't combine fetchpriority="high" with loading="lazy"
- Render-Blocking Resources — Even with priority, blocking CSS delays render
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.