Native image lazy loading
Images are typically the heaviest asset on the web. HTTP Archive data shows that at the 90th percentile, sites ship more than 5 MB of images on both desktop and mobile. Historically, deferring off-screen images required either the Intersection Observer API or scroll, resize, and orientationchange event handlers, often wrapped in a third-party library such as LazySizes.
The loading attribute gives you the same behavior natively, removing the need for a JavaScript dependency. Because support is built into the browser, deferred loading still behaves predictably, and the attribute only does its work when JavaScript is enabled. Browsers that don't support it simply ignore it, so there’s no downside to including it.
Using the loading attribute
Chrome already prioritizes images differently based on their position relative to the viewport, but off-screen images are still fetched during page load. The loading attribute changes that:
<img src="image.png" loading="lazy" alt="…">
Supported values are:
lazy: defers the fetch until the image approaches a calculated distance from the viewport.eager: the default, which loads the image regardless of its position. You might set this explicitly if tooling injectsloading="lazy"by default or your linter requires an explicit value, but it doesn’t make the image load faster than an image without the attribute.
For an image you want to prioritize—your LCP image, for example—combine fetchpriority="high" with the default loading behavior rather than lazy. An off-screen image with both loading="lazy" and fetchpriority="high" is still delayed until it nears the viewport; it then fetches with high priority, which is likely what the browser would have done on its own.
When images start loading
Images visible on first paint load normally. Off-screen images are fetched as the user scrolls toward them, early enough that they typically finish before entering the viewport. Chromium decides how early to fetch based on the resource type and the user’s effective connection type; you can inspect the defaults in the Chromium source and simulate different network conditions with DevTools throttling.
In July 2020, Chrome reduced those thresholds to align native lazy loading with the behavior of popular JavaScript libraries. On fast connections (4G), the distance threshold dropped from 3000px to 1250px; on slower connections (3G and below), it went from 4000px to 2500px. The smaller offsets still give images time to load before the user scrolls to them.
Dimensions matter more when deferring
The browser can’t reserve layout space for an image until it knows the image’s dimensions. Until width and height are present, dimensions default to 0×0 pixels:
<img src="image.png" loading="lazy" alt="…" width="200" height="200">
Setting dimensions is always good practice, but it’s especially important when lazy loading. Without them, a group of images can collapse to zero height, letting the browser conclude that all of them fit in the initial viewport and load everything right away. And when native lazy loading misses its timing, missing dimensions amplify the resulting layout shift.
You can apply loading="lazy" equally to images inside a <picture> element by putting the attribute on the fallback <img>:
<picture>
<source media="(min-width: 800px)" srcset="large.jpg">
<img src="small.jpg" loading="lazy" alt="…">
</picture>
Keep the first viewport eager
Images that render above the fold, and especially the LCP image, should use the default eager loading so they’re available as early as possible. Lazy loading can’t start until the browser has laid out the page enough to know an image’s position, which means visible images would arrive later than necessary. Reserve loading="lazy" for images outside the initial viewport:
<!-- LCP image: no lazy loading -->
<img src="hero.jpg" fetchpriority="high" alt="…">
<!-- Below-the-fold image: defer -->
<img src="below-fold.jpg" loading="lazy" alt="…">
Frequently asked questions about browser-level lazy loading
Does Chrome still auto-lazy-load images?
Previously, Chromium would automatically defer loading for images deemed suitable when Chrome for Android's Lite mode was enabled and the loading attribute was absent or set to loading="auto". Lite mode has since been deprecated, along with loading="auto", and there are currently no plans for Chrome to introduce automatic lazy loading for images.
Can I control the lazy-loading threshold distance?
The distance thresholds are hardcoded and cannot be changed through the API. Browsers may adjust these values in the future as they experiment with different distances and variables.
Does loading work on CSS background images?
No. The attribute can only be used with <img> tags.
What about images that are in the viewport but not visible?
Using loading="lazy" can prevent images from loading when they aren't visible but fall within the calculated distance threshold. This includes images hidden behind carousels or by CSS for certain screen sizes. Chrome, Safari, and Firefox do not load images styled with display: none;, either on the image itself or on a parent element. Other hiding techniques, like opacity:0, still cause the browser to load the image. Thoroughly test your implementation to confirm it behaves as expected.
Chrome 121 changed behavior for horizontally scrolling content like carousels: these now use the same thresholds as vertical scrolling. As a result, images in a carousel load before they become visible in the viewport, making loading less noticeable to users but increasing the number of downloads. You can compare behavior in Chrome versus Safari and Firefox with the Horizontal Lazy Loading demo.
Do I still need a third-party lazy-loading library?
With full support for lazy loading built into modern browsers, you generally don't need a third-party library or script. The main reasons to keep one are to polyfill the feature for browsers lacking support, or to gain finer control over when lazy loading triggers.
How do I handle browsers without support?
Browser-level lazy loading is well supported across major browsers and is recommended for standard use cases, eliminating extra JavaScript dependencies. If you must support additional browsers or want to control thresholds, a third-party library is the fallback option.
Feature detection is possible using the loading property:
if ('loading' in HTMLImageElement.prototype) {
// supported in browser
} else {
// fetch polyfill/third-party library
}
For example, lazysizes is a popular JavaScript lazy-loading library. You can detect support and load lazysizes as a fallback only when loading is unsupported:
- Replace
<img src>with<img data-src>to avoid eager loading in unsupported browsers. Ifloadingis supported, swapdata-srcforsrc. - If
loadingisn't supported, load a fallback from lazysizes and initiate it, using thelazyloadclass to mark images for lazy loading:
<!-- Let's load this in-viewport image normally -->
<img src="hero.jpg" alt="…">
<!-- Let's lazy-load the rest of these images -->
<img alt="…" class="lazyload">
<img alt="…" class="lazyload">
<img alt="…" class="lazyload">
<script>
if ('loading' in HTMLImageElement.prototype) {
const images = document.querySelectorAll('img[loading="lazy"]');
images.forEach(img => {
img.src = img.dataset.src;
});
} else {
// Dynamically import the LazySizes library
const script = document.createElement('script');
script.src =
'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js';
document.body.appendChild(script);
}
</script>
A demo of this pattern is available; testing it in an older browser shows the fallback in action.
Is lazy loading available for iframes?
Yes. <iframe loading=lazy> is standardized, letting you lazy-load iframes with the loading attribute. Browser support for iframe lazy loading covers Chrome 77+, Edge 79+, Firefox 121+, and Safari 16.4+. For more details, see the guide on lazy-loading offscreen iframes.
How does it affect advertisements?
Ads displayed as images or iframes lazy-load in the same way as any other image or iframe.
What happens when a page is printed?
All images and iframes load immediately upon printing. See Chromium issue #875403 for specifics.
Does Lighthouse recognize lazy loading?
Lighthouse 6.0 and higher accounts for offscreen image lazy-loading approaches that use different thresholds, allowing them to pass the Defer offscreen images audit.
Improving performance with lazy loading
Browser-level lazy loading for images makes it significantly easier to improve page performance metrics. If you encounter unusual behavior with this feature in Chrome, file a bug report with the Chromium team.



