How to lazy-load images
How native lazy-loading works, and the one image on every page that should never use it.
Lazy loading delays fetching an image until a visitor is about to scroll near it, instead of downloading every image on the page immediately. On a long page with many images, most of them below what is initially visible, this means the browser spends its early bandwidth on what the visitor can actually see first, rather than competing to fetch a footer image nobody has scrolled to yet.
How to apply it
Browsers support this natively through the loading attribute, with no script required:
<img src="photo.webp" loading="lazy" width="800" height="450" alt="...">
Setting it to lazy tells the browser to defer the request until the image is close to entering the viewport. Setting it to eager, or leaving the attribute off entirely, loads it immediately along with the rest of the page — which is what you want for anything visible without scrolling.
Which images should use it
- Images further down a long page — a blog post's inline photos, a product listing's later results, a gallery beyond the first few thumbnails.
- Images inside content that is not visible until interaction — a tab panel, an accordion, a modal that is not open by default.
- Anything in a footer or a "related content" section at the bottom of the page.
The one image that must never be lazy-loaded
The image at the top of the page — a hero banner, a featured photo, whatever is visible the instant the page loads — should never use loading="lazy". This is usually the element measured by Largest Contentful Paint, and lazy loading it tells the browser to deliberately wait before fetching the exact thing that metric is timing. Leave it as a normal, eager-loaded image, and consider adding fetchpriority="high" to it instead — see improving Largest Contentful Paint for the full reasoning.
A reasonable rule of thumb: anything visible in the first screenful a visitor sees, on the device size you care most about, loads eagerly. Everything below that can lazy-load safely.
What lazy loading does not do
It changes when an image is requested, not how large the file is. A five-megabyte image that has been lazy-loaded is still a five-megabyte image once a visitor actually scrolls to it — lazy loading defers the cost, it does not remove it. Compressing images properly is a separate, equally necessary step, and the two work together rather than either one substituting for the other.
It also has no effect on images that are already visible on load — applying it there either does nothing useful or, in the case of the first visible image, actively slows down the metric that matters most for a first impression.
Always keep width and height set
Lazy-loaded images still need width and height attributes so the browser can reserve the correct space in the layout before the image has actually loaded in. Skipping this on a lazy-loaded image is a common cause of content jumping around as a visitor scrolls — exactly the problem covered in fixing Cumulative Layout Shift.
Checking it is actually working
Open developer tools, go to the network panel, load a long page with images, and watch the request list as you scroll rather than reload the page. Correctly lazy-loaded images should appear in the network panel only as you scroll near them, not all at once when the page first loads. If every image loads immediately regardless of the attribute, check that the markup was actually applied — a template or plugin sometimes strips or overrides attributes it does not recognise.
Related reading
How to get images down to a sensible size for the web without the loss of quality being visible.
How to improve Largest Contentful PaintHow to find the specific element dragging down your LCP score, and the fixes that actually move it.
How to serve WebP imagesHow WebP compares to older image formats, and how to add a fallback for the rare browser that needs one.
How to reduce the number of requests a page makesWhy every extra file a page loads adds delay, and how to cut the number down without changing how the page looks.