Skip to content
ExponaBLOG
TECHNICAL SEO FOR DEVELOPERS · DAY 041 / 100

fetchpriority for your hero image: a step-by-step guide

One attribute that often improves LCP.

Expona Admin6 min read

Largest Contentful Paint (LCP) is one of the three Core Web Vitals that Google uses to rank your site, and it often hinges on a single element: your hero image. One attribute that often improves LCP is fetchpriority, a browser hint that tells the browser exactly when to fetch your most critical images. In this post, I'll show you how to use fetchpriority='high' on your hero image and why this small change can shave 500ms off your LCP in real-world conditions.

Understanding fetchpriority and why it matters for LCP

When you load a web page, the browser has limited bandwidth and must decide which resources to fetch first. By default, the browser uses heuristics—it might prioritize stylesheets and scripts, then images, then fonts. For a hero image that dominates your viewport, this can mean a 1-2 second delay while the browser fetches lower-priority resources first.

The fetchpriority attribute gives you explicit control over this prioritization. When you add fetchpriority='high' to an image, you're telling the browser: "This image is critical to the user experience. Fetch it before other images." On a 3G connection or with multiple images on the page, this can be the difference between an LCP of 3 seconds and 2 seconds.

I've seen this play out in practice. A client's SaaS dashboard had an LCP of 2.8 seconds, driven entirely by a large chart graphic that sat above the fold. Adding fetchpriority='high' dropped that to 2.1 seconds—a 25% improvement with a one-line change.

fetchpriority='high' on the LCP image

The basic implementation is straightforward. Identify which image on your page is most likely to be your LCP—usually the hero image, a large banner, or a critical chart. Add the attribute directly to the <img> tag:

html
<img src="/hero.webp" alt="Dashboard"
  fetchpriority="high" width="1200" height="630">

That's it. The browser will now prioritize fetching this image above other images on the page. But there's a catch: you should only use fetchpriority='high' on one, maybe two images per page. Using it on every image defeats the purpose—you're not prioritizing anything if everything is high priority.

In my experience, the best candidates for fetchpriority='high' are:

  • Hero images that cover most of the viewport
  • Above-the-fold product images in e-commerce
  • Large thumbnails or featured images that render immediately
  • Background images used as visual anchors (though we'll cover a better approach for these)

A real example: I worked on a travel booking site where the hero image showed destination photos. That image was 600KB and often delayed LCP by 400ms. Setting fetchpriority='high' and optimizing the format cut LCP by 600ms total.

Never lazy-load above-the-fold images

This is where I see the most common mistake: developers add loading='lazy' to images thinking it helps performance, then wonder why their LCP is poor. If an image is above the fold—visible without scrolling—you should never lazy-load it.

Lazy loading tells the browser to delay fetching the image until it's likely to enter the viewport. For an image already in the viewport, this just wastes time. The browser fetches the image late, the user sees a blank space or placeholder, and LCP is delayed.

html
<!-- WRONG: above-the-fold image with lazy loading -->
<img src="/hero.webp" alt="Dashboard" loading="lazy" width="1200" height="630">

<!-- CORRECT: above-the-fold image, no lazy loading -->
<img src="/hero.webp" alt="Dashboard" fetchpriority="high" width="1200" height="630">

Reserve loading='lazy' for images that appear below the fold. A rule of thumb I use: if it's on the first screen, eager load it; if it's below, lazy load it. Your LCP image should never have loading='lazy'.

One more thing: if you're using responsive images with srcset and sizes, you still only need fetchpriority='high' on the <img> element itself. The browser applies the priority hint to all variants:

html
<img src="/hero.webp" alt="Dashboard"
  srcset="/hero-sm.webp 640w, /hero-lg.webp 1200w"
  sizes="(max-width: 640px) 100vw, 1200px"
  fetchpriority="high" width="1200" height="630">

next/image priority does this for you

If you're using Next.js, the next/image component can handle this automatically. When you set priority={true}, Next.js does two things: it preloads the image in the document head and sets the equivalent of fetchpriority='high' on the rendered <img> tag.

html
<Image
  src="/hero.webp"
  alt="Dashboard"
  width={1200}
  height={630}
  priority
/>

That priority prop saves you a few steps. But I want to be clear: priority in Next.js does more than just fetchpriority. It also adds a preload link to your head and disables lazy loading by default. This is why it's so effective.

One nuance: next/image optimization happens at build time or request time (depending on your setup), so you get additional benefits like automatic format conversion and resizing. For your LCP image, this is almost always the right choice in a Next.js project.

I've optimized several Next.js apps where setting priority on the hero image was the single highest-impact change. Combined with WebP format and proper sizing, LCP often drops by 40-50%.

Preload background images used as heroes

Not every hero is an <img> tag. Sometimes you're using a CSS background image on a div, especially in design-heavy sites. Background images don't participate in LCP calculation (only <img>, <svg>, and video elements do), but they still need to be fetched, and slow background images hurt perceived performance.

For background images, you want a preload link in your document head:

html
<head>
  <link rel="preload" as="image" href="/hero-bg.webp" type="image/webp">
</head>
<body>
  <div class="hero" style="background-image: url('/hero-bg.webp');">
    <!-- content -->
  </div>
</body>

This tells the browser to fetch the image as soon as it parses the head, without waiting to parse the CSS. On a 3G connection, this can save a full second compared to waiting for CSS to be parsed, computed, and then the image fetched.

In React or Next.js, you can add this link in the head component:

html
<Head>
  <link rel="preload" as="image" href="/hero-bg.webp" type="image/webp">
</Head>

Be careful: don't preload every background image. Preload is a resource hint, and overusing it can bloat your HTML and confuse the browser's prioritization. Preload only the hero or critical above-the-fold background image.

Common mistakes

Mistake 1: Using fetchpriority='high' on multiple images. I've seen pages with 5+ images marked as high priority. This defeats the purpose—the browser can't tell which one is actually most important. Stick to one, maybe two per page.

Mistake 2: Combining lazy loading with high priority. Some developers add both loading='lazy' and fetchpriority='high' expecting the best of both worlds. In reality, browsers are inconsistent; lazy loading will still delay the image, and high priority won't override it reliably. Choose one strategy per image.

Mistake 3: Using fetchpriority on images you haven't tested. Measure your LCP before and after. I've seen cases where the actual LCP element wasn't the hero image but a text element that rendered late due to a blocking font. Use DevTools (Performance tab or Lighthouse) to confirm what's actually causing LCP delay.

Mistake 4: Forgetting dimensions on images with fetchpriority. Always add width and height attributes. Without them, the browser can't reserve space, and you get layout shift when the image loads. This hurts Cumulative Layout Shift (CLS), another Core Web Vital.

Mistake 5: Not optimizing the image itself. fetchpriority helps, but it doesn't replace format optimization. A 2MB JPEG will always be slow. Use WebP or AVIF, compress aggressively, and serve responsive sizes. fetchpriority is a multiplier on an already-optimized image, not a magic bullet.

Key takeaways

  • fetchpriority='high' tells the browser to fetch a critical image before other images, often improving LCP by 200-600ms depending on conditions.
  • Apply fetchpriority='high' only to your single most important above-the-fold image—usually the hero.
  • Never combine lazy loading (loading='lazy') with above-the-fold images; use eager loading by default.
  • In Next.js, the priority prop on next/image handles preloading and priority hints automatically.
  • For CSS background images, use a <link rel="preload"> in the head to fetch them early.
  • Measure your LCP before and after to confirm the attribute is actually helping—not every page's bottleneck is image fetching.
  • Optimize the image file itself (format, size, compression) before relying on browser hints; they multiply the benefit of a already-lean asset.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles