DEV Community

Anas Sheikh
Anas Sheikh

Posted on

Adding priority to Every Image in Next.js Can Actually Make Your Site Slower

This is a genuinely counterintuitive one, since the natural instinct when trying to speed up image loading is to mark more images as high priority, and that instinct, applied broadly, actively works against the exact goal it's trying to achieve.

What priority Actually Does

<Image src="/hero.jpg" alt="Hero" width={1200} height={600} priority />
Enter fullscreen mode Exit fullscreen mode

The priority prop tells Next.js to preload this specific image, fetching it immediately, ahead of the browser's normal lazy-loading behavior, and to skip the default loading="lazy" treatment entirely. This exists specifically for the one image that matters most for perceived load speed, usually the hero image or whatever's driving your Largest Contentful Paint metric, the specific thing a visitor sees first and that most directly determines how fast the page feels to load.

Why More Priority Images Feels Like It Should Help

The instinct is understandable, if priority makes one image load faster, marking several important-looking images as priority should make the whole page feel faster, right. This reasoning treats "priority" as a simple speed boost you can apply liberally, more of a good thing being better, rather than what it actually is, a request to the browser to allocate scarce, limited bandwidth and rendering attention to this specific resource first, ahead of everything else.

What Actually Happens With Multiple priority Images

// A product page marking every product thumbnail as priority
{products.map((product) => (
  <Image
    key={product.id}
    src={product.image}
    alt={product.name}
    width={300}
    height={300}
    priority // applied to every single one
  />
))}
Enter fullscreen mode Exit fullscreen mode

Every image marked priority competes for the same limited early bandwidth and browser attention simultaneously. Instead of one clear, fast-loading LCP element, the browser is now juggling ten, twenty, however many priority requests all at once, none of which gets the focused, immediate loading priority was actually designed to provide. The specific image that should have been your fastest, most important visual element now loads alongside, and competes against, a dozen others that never needed that treatment in the first place, and your actual LCP timing often gets measurably worse, not better, than if only the genuinely critical image had been marked.

Why This Doesn't Show Up Obviously in Casual Testing

On a fast connection, with a small number of images, and especially in local development, the practical difference between one priority image and ten is often small enough to not be obviously noticeable just clicking around. The real cost shows up specifically on a slower connection, mobile networks in particular, or on a page with genuinely many images, exactly the conditions where LCP optimization matters most in the first place, and exactly the conditions a developer testing casually on a fast office connection is least likely to be experiencing themselves.

The Actual Rule: One, Maybe Two, Never More Than That

priority should go on the single image that's actually your LCP element, the largest, most prominent visual content visible without scrolling, and essentially nothing else. For a typical page, that's one image. Occasionally a genuine case exists for two, a hero image plus one other unusually prominent above-the-fold element, but the number should be small and deliberate, never applied as a blanket default across a loop of images or a whole gallery.

// ✅ One deliberate priority image, everything else loads normally
export default function ProductPage({ product, related }) {
  return (
    <div>
      <Image src={product.mainImage} alt={product.name} width={800} height={800} priority />

      <div className="grid">
        {related.map((item) => (
          <Image key={item.id} src={item.image} alt={item.name} width={200} height={200} />
          // no priority here, these genuinely benefit from normal lazy loading
        ))}
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The related products grid, below the main image and likely below the fold on most screens anyway, doesn't need or benefit from eager loading, letting them lazy-load normally is not just acceptable, it's actually the better choice for overall page performance.

How to Actually Identify Your Real LCP Element

Chrome DevTools' Performance panel, or a Lighthouse report, directly identifies which specific element on your page is being measured as the Largest Contentful Paint, rather than guessing based on which image looks most important. This is worth checking directly rather than assuming, since the actual LCP element is sometimes a different image than intuition would suggest, particularly on pages with unconventional layouts.

Checking Your Own Codebase

grep -rn "priority" --include="*.tsx" app/ components/ | grep -i image
Enter fullscreen mode Exit fullscreen mode

If this turns up priority inside a .map() loop, applied to every item in a list or grid, that's almost certainly this exact issue, worth reconsidering down to the single genuinely critical image, or removing it from the loop entirely if nothing in that specific list is actually the page's real LCP element.

The Actual Rule

priority is a scarce resource allocation, not a generic speed setting, and using it on multiple images doesn't compound the benefit, it dilutes it. One deliberate, correctly identified LCP image with priority, everything else loading normally, reliably outperforms a page where several images all compete for the same eager-loading treatment simultaneously.


If you've got priority applied inside a .map() loop or on more than one or two images on any given page, worth checking your actual Lighthouse LCP score before and after trimming it down to just the real LCP element. Drop what you find in the comments, genuinely curious how much this moves the needle in practice across different real projects.

Get the templates: https://pixelanas.gumroad.com


Anas, full-stack Next.js developer building SaaS products and premium templates. X: @ASheikh69751

Top comments (0)