Why You Shouldn't Lazy-Load Every Image
Native image lazy loading is one of the easiest performance features to use.
Add one attribute:
<img
src="/images/photo.webp"
alt="A photograph"
loading="lazy"
>
and the browser can delay loading the image until it is closer to the viewport.
That is useful for images far down a long page.
The problem starts when loading="lazy" gets added to every image, including the main image at the top of the page.
Lazy loading is not automatically better.
What lazy loading does
Without lazy loading, the browser discovers an image and can start loading it.
With:
loading="lazy"
the browser may delay the request because the image is not needed yet.
That can save bandwidth and reduce work during the first page load.
For an image 3000 pixels down the page, that is great.
The hero image is different
Imagine this:
<main>
<h1>My photography portfolio</h1>
<img
src="/hero.webp"
alt="Portrait photographed outdoors"
loading="lazy"
>
</main>
The hero image is already visible when the page opens.
The user needs it now.
Telling the browser to lazy-load it can delay an important request.
If that image becomes the Largest Contentful Paint element, the delay can hurt LCP.
Google’s web performance guidance also recommends avoiding lazy loading for images that are visible in the initial viewport, especially likely LCP images: web.dev on lazy loading.
Better hero markup
<img
src="/hero.webp"
alt="Portrait photographed outdoors"
fetchpriority="high"
width="1600"
height="1067"
>
Notice what is missing:
loading="lazy"
For the main above-the-fold image, let the browser load it normally.
fetchpriority="high" can be useful when you are confident this is the important LCP image.
Do not add high priority to every image.
Lazy-load images below the fold
Further down:
<img
src="/gallery-01.webp"
alt="Street photograph in Riga"
loading="lazy"
width="1200"
height="800"
>
This is a much better lazy-loading candidate.
If the user never scrolls that far, the browser may never need to download it.
A simple rule
I use a rough rule like this:
Visible when page opens?
↓
Load normally
Further down the page?
↓
Consider loading="lazy"
It is not perfect, but it is better than adding lazy loading everywhere.
Width and height still matter
Lazy loading does not replace:
width="1200"
height="800"
These values let the browser reserve the right amount of space before the image loads.
Without them, content can jump when the image appears.
That can increase Cumulative Layout Shift.
Responsive images still matter
Lazy loading also does not fix oversized files.
This:
<img
src="/photo-4000.webp"
loading="lazy"
>
may still download a huge file later.
Use srcset:
<img
src="/photo-800.webp"
srcset="
/photo-400.webp 400w,
/photo-800.webp 800w,
/photo-1600.webp 1600w
"
sizes="(max-width: 800px) 100vw, 800px"
loading="lazy"
alt="Street photograph"
>
Now the browser can choose a more suitable size.
Background images are different
loading="lazy" does not apply to CSS background images:
.hero {
background-image: url("/hero.webp");
}
This is another reason important content images are often better as real <img> elements.
What about logos?
A logo at the top of a page is normally visible immediately.
I would not lazy-load it.
It is usually small anyway.
<img
src="/logo.svg"
alt="Company name"
width="160"
height="40"
>
What about thumbnails?
A grid that starts below the first screen is a good case:
<img
src="/thumb-01.webp"
alt="Project preview"
loading="lazy"
>
If the first row is already visible, you may choose to load those first images normally and lazy-load later rows.
You do not need a complicated system unless the page is very image-heavy.
Iframes too
Native lazy loading also works for iframes:
<iframe
src="https://example.com/embed"
loading="lazy">
</iframe>
This can help a lot for embeds that appear far down an article.
Again, if the iframe is the main content at the top, delaying it may not make sense.
Measure the actual page
If Lighthouse reports that your LCP image was lazily loaded, remove the lazy attribute and test again.
If a long gallery downloads dozens of images before the user scrolls, lazy loading can help.
The goal is not to use the attribute.
The goal is to load important things early and unimportant things later.
Lazy loading is a tool, not a rule
loading="lazy" is a very good feature.
It is also easy to overuse because adding it feels harmless.
Use lazy loading for content the user may not reach yet.
Let important content load.