Lazy-Loading and Responsive Images: A Practical Starter Guide

Published on June 4, 2024 • Updated on September 15, 2026

Quick summary

Speed up your site with native lazy-loading and responsive images: loading=lazy, srcset and picture, with copy-paste snippets.

Topic: Image tools

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:

  1. Lazy-Loading: Defer the loading of off-screen images until the user scrolls near them.
  2. 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 and height 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:

  1. 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.
  2. 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 the srcset.
  • src: This is a fallback for older browsers that don’t support srcset.

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.

Measuring the Win: Before and After with Lighthouse

Do not ship blind. Prove the gain in five minutes:

  1. Baseline: Run Lighthouse on a representative image-heavy page and note LCP, CLS, and total image bytes.
  2. Apply the trio: Eager-load the hero, lazy-load the rest, add srcset widths, and set explicit dimensions everywhere.
  3. Re-run twice: Take the better of two runs (caches and network vary). A healthy result is LCP down by a second or more and image bytes cut by half on mobile widths.
  4. Watch the field: Lab numbers are instant, but CrUX field data in PageSpeed Insights confirms real-user improvement within a month.
Advertisement

Frequently asked questions

Should I lazy-load every image on the page?

No. Lazy-load below-the-fold images only; the hero or LCP image must load eagerly, ideally with fetchpriority=high. Lazy-loading the visible image delays your largest paint.

Why do my images cause layout shift?

Because the browser reserves zero height until the file arrives. Always set width and height (or aspect-ratio in CSS) so the space is reserved before loading.

srcset or picture: which do I need?

Use srcset for the same image at different sizes, and picture for different images per breakpoint or format switching like AVIF with a JPEG fallback. Most sites need srcset everywhere and picture in a few art-directed spots.

Does lazy-loading hurt SEO?

Not when done natively: Googlebot renders and scrolls, so loading=lazy images get discovered. Avoid JavaScript-only lazy-loaders that depend on scroll events bots may never fire.

How do I generate the resized variants?

Export 480, 800, and 1200px versions once with our Image Resizer, convert to WebP with our Image Converter, then reference all three in one srcset.

Use the tool

Ready to apply this guide?

Open the related tool and finish the task in your browser without uploads or extra setup.

Image Resizer & Cropper

Change dimensions and crop images.

Explore this topic

Image tools

Read more guides in this cluster and move between related tools faster.

View topic guides

Useful tools

Related Guides