Lazy Loading Images: Complete Guide 2026
Lazy loading is one of the simplest and most impactful performance optimizations you can apply to a website. By deferring the loading of images that are not visible in the viewport, you reduce initial page weight, accelerate first render, and save bandwidth for users who never scroll to the bottom of the page.
Native lazy loading: one attribute
Since 2019, all major browsers support the loading attribute on <img> and <iframe> elements. No JavaScript library needed:
<img src="photo.jpg" alt="Description" loading="lazy">
The browser only downloads the image when the user scrolls within a certain distance of it. The threshold varies by browser and connection speed, typically 1,250 px to 2,500 px ahead of the viewport.
The three values of loading=
| Value | Behaviour | When to use |
|---|---|---|
lazy |
Deferred until near the viewport | All below-fold images |
eager |
Loaded immediately (default behaviour) | Above-fold images, especially the LCP image |
auto |
Browser decides (mostly same as eager) | Not recommended, prefer explicit values |
Critical rule: never lazy-load above-fold images
The most common lazy loading mistake is applying it to every image on the page, including the hero image. This delays the Largest Contentful Paint (LCP), the Google metric that measures when the main content is visible. A lazy-loaded LCP image can drop your LCP score dramatically.
loading="lazy". Use loading="eager" or simply omit the attribute. Ideally, preload it with a <link rel="preload"> tag.
Always add width and height
Lazy loading works best when the browser knows the dimensions of images before they load. Without width and height, the browser cannot reserve space, causing layout shifts (CLS) when images load in:
<!-- Correct: dimensions specified -->
<img src="photo.jpg" alt="..." width="800" height="600" loading="lazy">
<!-- Wrong: no dimensions, will cause layout shift -->
<img src="photo.jpg" alt="..." loading="lazy">
Lazy loading with srcset
Lazy loading is fully compatible with responsive images:
<img
srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1200.webp 1200w"
sizes="(max-width: 600px) 100vw, 800px"
src="photo-800.webp"
alt="Description"
width="800" height="600"
loading="lazy"
>
Lazy loading with the <picture> element
<picture>
<source srcset="photo.avif" type="image/avif">
<source srcset="photo.webp" type="image/webp">
<img src="photo.jpg" alt="Description" width="800" height="600" loading="lazy">
</picture>
The loading attribute goes on the <img> element, not the <picture> or <source> elements.
Browser support
Native lazy loading is supported in all modern browsers as of 2026: Chrome 76+, Firefox 75+, Safari 15.4+, Edge 79+. For older browsers, omitting the attribute simply loads all images immediately, a safe, graceful degradation. No polyfill is needed.
When to use a JavaScript lazy loader
The native attribute covers the vast majority of use cases. A JavaScript library (such as lazysizes) may still be useful if:
- You need to support very old browsers (Safari 14 and below)
- You are lazy-loading CSS background images
- You need custom loading thresholds or callbacks
loading="lazy" to every image below the fold. Never apply it to your LCP image. Always specify width and height to prevent layout shifts. This one-line change typically reduces initial page download weight by 30–50% on image-heavy pages.
Try imgpact tools
Free browser-based image tools, no upload, no signup.