Lazy-Loading and Responsive Images: A Practical Starter Guide
The Problem: Images Are Heavy
Images are often the largest files on a webpage. When a user visits your site, their browser tries to download every single image, including those that are far down the page and not yet visible. This wastes bandwidth and significantly slows down the initial page load, leading to a poor user experience and lower Core Web Vitals scores.
The solution is two-fold:
- Lazy-Loading: Defer the loading of off-screen images until the user scrolls near them.
- Responsive Images: Serve different image sizes to different screen sizes, so a mobile user doesn’t have to download a massive desktop-sized image.
Fortunately, modern HTML provides powerful and easy-to-use features to implement both.
Part 1: Effortless Lazy-Loading
In the past, lazy-loading required complex JavaScript libraries. Today, it’s a simple attribute.
The loading="lazy"
attribute tells the browser not to load an image until it is about to enter the viewport.
How to Implement It:
Simply add loading="lazy"
to your <img>
tags.
<img src="my-image.jpg" alt="A descriptive alt text" loading="lazy" width="800" height="600">
Important:
- Always include
width
andheight
attributes. This allows the browser to reserve the correct amount of space for the image before it loads, preventing layout shifts (CLS - Cumulative Layout Shift). - Don’t lazy-load everything. For images that are “above the fold” (visible in the initial viewport), you should let them load normally. Lazy-loading them can actually slow down the perceived load time. The
loading="lazy"
attribute is for images that are further down the page.
Browser support for loading="lazy"
is now universal across all major browsers, making it a safe and effective performance boost.
Part 2: Serving the Right Size with srcset
Why should a user on a small phone screen download a 2000px-wide image designed for a large desktop monitor? The srcset
attribute lets you provide the browser with a list of different-sized versions of an image. The browser then intelligently chooses the most appropriate one to download based on the user’s screen size and resolution.
How to Implement It:
-
Create Multiple Image Sizes: First, you need to create a few versions of your image. A common set might be:
image-small.jpg
(e.g., 480px wide)image-medium.jpg
(e.g., 800px wide)image-large.jpg
(e.g., 1200px wide) You can create these with our Image Resizer tool.
-
Use the
srcset
Attribute: List each image followed by its width descriptor (w
).
<img
srcset="image-small.jpg 480w,
image-medium.jpg 800w,
image-large.jpg 1200w"
sizes="(max-width: 600px) 480px,
800px"
src="image-medium.jpg"
alt="A descriptive alt text"
loading="lazy"
width="800" height="600">
Let’s break that down:
srcset
: Provides the list of available images and their actual widths.sizes
: This tells the browser how wide the image will be displayed at different viewport sizes. In this example, it says: “If the screen is 600px wide or less, the image will be 480px wide. Otherwise, it will be 800px wide.” The browser uses this information to pick the best image from thesrcset
.src
: This is a fallback for older browsers that don’t supportsrcset
.
Part 3: Art Direction with the <picture>
Element
Sometimes, you don’t just want to serve a smaller version of an image; you want to serve a different image entirely. For example, a wide landscape shot on desktop should be a tighter, cropped portrait shot on mobile. This is called “art direction.”
The <picture>
element is perfect for this. It allows you to provide multiple <source>
elements, and the browser will pick the first one that matches.
How to Implement It:
<picture>
<!-- Show this image if the screen is 600px or less -->
<source media="(max-width: 600px)" srcset="image-portrait.jpg">
<!-- Otherwise, show this image -->
<source media="(min-width: 601px)" srcset="image-landscape.jpg">
<!-- Fallback for older browsers -->
<img src="image-landscape.jpg" alt="A descriptive alt text" loading="lazy" width="1200" height="600">
</picture>
You can also use <picture>
to serve modern image formats like AVIF or WebP with a JPEG fallback:
<picture>
<source type="image/avif" srcset="image.avif">
<source type="image/webp" srcset="image.webp">
<img src="image.jpg" alt="A descriptive alt text">
</picture>
You can create these different formats using our Image Converter tool.
Conclusion
By combining these three modern HTML features, you can build websites that load incredibly fast on any device.
- Use
loading="lazy"
for all images below the fold. - Use
srcset
to provide different sizes of the same image. - Use
<picture>
when you need to provide different images for different screen sizes or formats.
Implementing these techniques is one of the highest-impact changes you can make to improve your site’s performance and Core Web Vitals.