Yes, for images below the first screen, and no for the ones a reader sees the moment the page opens, above all the largest one. Add loading="lazy" to images further down the page so the browser fetches them only as the reader scrolls near them. Leave it off the main image at the top, mark that one fetchpriority="high", and give every image a width and height. Lazy loading everything is a common mistake: it saves bytes but makes the page look slower.
What does loading="lazy" do?
It tells the browser it may wait to fetch an image until the image comes close to the screen. web.dev's guide (last updated Aug 13, 2024) lists the two values:
| Value | What the browser does |
|---|---|
lazy |
Waits until the image is within a set distance of the screen |
eager |
Fetches it right away, wherever it is on the page (the same as leaving the attribute out) |
It needs no script and no library. In Chrome, "close" means about 1,250 pixels away on a fast connection and 2,500 pixels on 3G or slower, figures web.dev gives since a change in July 2020. You cannot set that distance yourself.
Two details surprise people. MDN notes that loading is only deferred when JavaScript is on, as a guard against tracking how far a reader scrolls. And an image hidden with display: none is not fetched at all in Chrome, Safari and Firefox, while one hidden with opacity: 0 still is.
Which browsers support it?
Nearly all of them. Can I use data updated Nov 5, 2026 put full support at 96.69% of global usage, plus 0.55% that lazy load images but not iframes, 97.24% for images in all. Chrome has supported it since version 77, Edge since 79, Firefox since 75 for images, and Safari since 15.4 for images. A browser that does not know the attribute simply ignores it and loads the image as usual, so adding it never breaks anything.
Why should you not lazy load the image at the top?
Because the browser cannot know a lazy image is on the screen until it has laid out the page, so it starts fetching later than it would have. If that image is the page's Largest Contentful Paint, the moment the page looks ready arrives later too. web.dev's own guide says it in one line: "Don't lazy-load images that are likely to be in-viewport".
The clearest test is an A/B study web.dev published (last updated Mar 31, 2022) on a WordPress demo site, nine runs of each case:
| Archive page, median | Lazy load everything | No lazy loading | Lazy load only below the first screen |
|---|---|---|---|
| LCP on desktop | 2,029 ms | 1,759 ms | 1,749 ms |
| LCP on mobile | 1,657 ms | 1,403 ms | 1,352 ms |
| Image bytes on desktop | 577 KB | 1,173 KB | 577 KB |
Lazy loading everything sent half the image bytes but was 13% to 15% slower to show the main content. Loading the first screen normally and the rest lazily got both: the speed of no lazy loading and the savings of lazy loading, and on mobile it was even a little faster than either, which the authors put down to less competition for the network. The authors proposed that same fix for WordPress core.
The mistake is still common. The HTTP Archive Web Almanac 2025 (published Jan 15, 2026) found that about 16% to 17% of pages lazy load their LCP image, with the native attribute on 10.4% of mobile pages and script tricks such as data-src on 5.9%.
What should the main image get instead?
fetchpriority="high". Browsers do not treat images as urgent even when one of them is the largest thing on the screen, and this attribute asks them to. web.dev's Fetch Priority guide shows Google Flights' LCP falling from 2.6 seconds to 1.9 seconds with it. It works in Chrome and Edge since version 102, Firefox since 132 and Safari since 17.2, and the Web Almanac 2025 counted it on 17.3% of mobile pages whose LCP is an image.
Putting loading="lazy" and fetchpriority="high" on the same image does not help: web.dev explains that the image is still held back while it is off the screen, and only then fetched quickly. Choose one per image.
A page often looks like this:
<!-- the main image: fetched at once, and first -->
<img src="hero.avif" alt="What the image shows" width="1600" height="800" fetchpriority="high">
<!-- the first row of cards, also on the first screen: the default -->
<img src="card-1.avif" alt="..." width="400" height="300">
<img src="card-2.avif" alt="..." width="400" height="300">
<!-- everything further down -->
<img src="card-7.avif" alt="..." width="400" height="300" loading="lazy">
<img src="card-8.avif" alt="..." width="400" height="300" loading="lazy">
If the main image is a CSS background, the attribute cannot go on it. Preload it with <link rel="preload" as="image" href="hero.avif" fetchpriority="high"> instead, as the Fetch Priority guide advises.
Why do lazy images need a width and height?
So the page keeps its shape. MDN explains that an image that has not loaded is 0 by 0 pixels, so the text around it jumps when it arrives, which counts against Cumulative Layout Shift. web.dev adds a worse case: in a gallery of images with no sizes, every image takes up no room, the browser decides they all fit on the first screen, and it fetches every one of them, which is exactly what lazy loading was meant to avoid. Set width and height to the file's real proportions and let CSS scale it; our post on what size images should be for a website covers srcset and sizes, which work the same with lazy images.
Frequently asked questions
How many images should I load eagerly?
Those a reader sees without scrolling, on the smallest screen you care about. That is usually the main image plus the first row of a grid. A phone shows fewer than a laptop, but a lazy image that turns out to be on the screen still loads straight away once the browser has laid out the page, so erring toward lazy below the main image costs little.
Does lazy loading help SEO?
Indirectly, by making pages lighter and faster, as long as search engines can still find the images. Google's guide to lazy loading (last updated Dec 10, 2025) names the browser's built-in lazy loading as a safe method, because it does not depend on scrolling or clicking, and Google Search does neither. The same guide also advises against lazy loading anything likely to be visible when the page opens.
Do I still need a JavaScript lazy loading library?
Rarely. web.dev says you probably do not need one now that browsers do it themselves; keep one only to support very old browsers or to control exactly when images load.
Does loading="lazy" work on CSS background images?
No. It only applies to img elements (and iframes). A background image has to be deferred with your own script, or preloaded if it is the main image.
Does lazy loading delay the page's load event?
The other way round: MDN notes that the load event does not wait for lazy images, even ones on the screen, so a test that waits for "load" may finish before they appear.
What Heart Photos does
These are the rules our own pages follow, checked in the code on Nov 7, 2026:
- This blog. A post's lead image, and the image beside the list's heading, load at once with
fetchpriority="high", while the cards further down the list areloading="lazy". - The viewer. In the row of thumbnails under an open image, the 16 either side of it are fetched at once with high priority, since those are the ones in view, and the rest of the row waits lazily. In a long gallery that row can run to hundreds of files.
- The wall. Every tile carries its width and height, so the grid keeps its shape as images arrive, and every tile is lazy. The wall is laid out by script, so no tile can be found before the script runs; while an image is open, the tiles behind it are fetched at low priority so the image you are looking at comes first.
Every image Heart Photos serves is also an AVIF in the width the screen asks for, which matters more than any attribute: our post on AVIF vs JPEG XL vs WebP has the sizes we measured. To try it with your own images, open Heart Photos.