Blog Lazy-load images without hurting your layout

Lazy-load images without hurting your layout

2 min read

Lazy-load images without hurting your layout
TL;DR Add loading=lazy to below-the-fold images so they load only when needed, and always set width and height (or aspect-ratio) so the browser reserves space before the image loads. Do not lazy-load your LCP image; it should load eagerly with high priority.

Lazy loading is close to free performance: images below the fold only load when the user scrolls near them, saving bandwidth and speeding the initial page. The catch is that a careless version causes layout shift, the page jumping as images pop in. Here is how to get the win without the jank.

Turn it on natively

You do not need a library. The browser has it built in:

<img src="photo.jpg" loading="lazy" alt="..." />

loading="lazy" tells the browser to defer that image until it is about to scroll into view. Use it on below-the-fold images.

Reserve the space, always

This is the part people skip, and it is what causes the shift. If an image has no dimensions, the browser does not know how much room to leave, so the layout collapses and then jumps when the image arrives.

Give every image its size:

<img src="photo.jpg" loading="lazy" width="800" height="600" alt="..." />

Or reserve space with CSS aspect-ratio when the display size is fluid:

img { width: 100%; height: auto; aspect-ratio: 4 / 3; }

Either way, the browser holds the space in advance and nothing moves when the image loads.

Do not lazy-load the LCP image

The one image you must not lazy-load is the largest one above the fold, usually your Largest Contentful Paint element. Deferring it delays the very thing the metric measures, making the page feel slower.

Load that one eagerly, and ideally give it a high fetch priority so it arrives first:

<img src="hero.jpg" fetchpriority="high" width="1200" height="630" alt="..." />

Lazy-load everything else.

The two rules to remember

Lazy loading is simple once you hold two rules together. First, defer the images that are not visible yet. Second, always reserve their space so nothing shifts, and never defer the hero. Follow both and you get the bandwidth savings and the fast first paint, with none of the jumpy layout that gives lazy loading a bad name.

FAQ

How do I lazy-load images natively?

Add the loading=lazy attribute to an img tag. The browser then defers loading that image until it is about to scroll into view. No library needed; it is built into the platform and works well for below-the-fold images.

Why does lazy loading cause layout shift?

If an image has no reserved space, the page collapses where it will appear, then jumps when it loads. Setting width and height, or an aspect-ratio in CSS, lets the browser hold the space in advance so nothing shifts.

Should I lazy-load every image?

No. Never lazy-load the largest image above the fold, usually your LCP element, because deferring it makes the page feel slower. Load that one eagerly, ideally with a high fetch priority, and lazy-load the rest.