Lazy Loading & the loading Attribute
A typical page loads every image and iframe the moment the browser discovers them in the HTML—even the ones far below the fold that the user may never scroll to see. Native lazy loading defers those off-screen resources until the user actually scrolls near them, cutting initial network and CPU work with a single HTML attribute and zero JavaScript.
The loading Attribute
<img> and <iframe> support a loading attribute with three possible values.Value | Behavior |
|---|---|
loading="lazy" | Defer loading until the element is near the viewport |
loading="eager" | Load immediately, regardless of position (the default) |
loading="auto" | Let the browser decide (currently behaves like eager) |
lazy-image.html
<img src="chart-large.png" alt="Quarterly revenue growth chart" loading="lazy" width="800" height="450" />
lazy-iframe.html
<iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ" title="Embedded video" loading="lazy" width="560" height="315" ></iframe>
loading="lazy" is supported by every current major browser (Chrome, Edge, Firefox, Safari). Older browsers simply ignore the attribute and load the resource eagerly—it degrades gracefully with no polyfill required.How the Browser Decides "Near the Viewport"
Browsers use an internal distance threshold (roughly a few screen heights, though the exact value isn't standardized and varies by connection speed) to start fetching a lazily-loaded resource just before the user scrolls to it. The goal is that the image is already loaded, or close to it, by the time it enters view—so there's no visible pop-in on a reasonably fast connection.
Why It Improves Initial Load and Core Web Vitals
Deferring off-screen media has a direct, measurable effect on page performance metrics:
Fewer simultaneous network requests on initial page load, so critical resources (fonts, above-the-fold images, scripts) get bandwidth sooner.
Less work for the browser to decode and paint up front, improving Largest Contentful Paint (LCP) for the content that actually matters first.
Lower memory usage on pages with dozens or hundreds of images, especially on mobile devices.
Reduced Total Blocking Time, since the main thread isn’t busy decoding images nobody has scrolled to yet.
When NOT to Lazy-Load
loading="lazy". Lazy loading adds a small evaluation delay before the browser even starts fetching the image, which directly worsens LCP for exactly the element that metric measures. Leave above-the-fold images at their default (eager) loading, or explicitly mark the single most important one with fetchpriority="high".above-the-fold-hero.html
<!-- Hero image: visible immediately, likely the LCP element.
Do NOT lazy-load this one. -->
<img
src="hero-banner.jpg"
alt="Product launch banner"
fetchpriority="high"
width="1600"
height="600"
/>
<!-- Gallery images further down the page: perfect for lazy loading -->
<img src="gallery-1.jpg" alt="Gallery photo 1" loading="lazy" width="400" height="300" />
<img src="gallery-2.jpg" alt="Gallery photo 2" loading="lazy" width="400" height="300" />Do lazy-load: images and iframes below the fold—galleries, comment sections, footer embeds.
Do not lazy-load: the hero image, logo, or any element likely to be the LCP candidate.
Do not lazy-load: images inside a carousel’s first visible slide.
Always Set width and height
width and height attributes. They let the browser reserve the correct space in the layout before the image loads, preventing a layout shift when a lazy image finally pops in.loading="lazy" together give you fast initial loads and a stable layout—two separate Core Web Vitals wins from a few HTML attributes.Quick Reference
Element | Attribute | Effect |
|---|---|---|
<img> | loading="lazy" | Defers loading until near viewport |
<iframe> | loading="lazy" | Defers loading until near viewport |
<img> | fetchpriority="high" | Marks an image as high priority (use for LCP candidates) |
<img> / <iframe> | width / height | Reserves layout space, prevents layout shift |
loading="lazy" to everything below the fold.