Skip to content
universalImage Compressor

Blog

Responsive Images, srcset and Lazy Loading Explained

One image file cannot be perfect for a phone and a large monitor. HTML has built-in tools to solve this.

By the Universal Image Compressor Team

The problem

A website is viewed on screens from 320 pixels wide to more than 3000. If you publish one image at 2000 pixels, phones download far more data than they can display. If you publish one at 600 pixels, large screens show a blurry picture. Responsive images solve this by letting you offer several versions of the same picture and leaving the choice to the browser, which knows the screen size, the pixel density and the user's settings.

This is not a trick for experts. The markup is short, and the files can be produced in a few minutes with a batch tool such as the compressor on this page.

srcset and sizes

The srcset attribute lists the available files with their widths. The sizes attribute tells the browser how wide the image will be displayed in the layout. With these two, the browser calculates which file is the best fit and downloads only that one. A simple example looks like this:

<img src="photo-1280.jpg"
     srcset="photo-640.jpg 640w, photo-1280.jpg 1280w, photo-1920.jpg 1920w"
     sizes="(max-width: 700px) 100vw, 700px"
     width="1920" height="1280" alt="Description of the photo">

The w value is the width of each file in pixels. The src attribute is the fallback for browsers that do not understand srcset. The browser may also choose a larger file on a dense screen, and it may reuse a version that is already cached.

Producing the versions

For each important image, create two to four widths, for example 640, 1280 and 1920 pixels. In the compressor, add the original, set the maximum size to one of the widths (it limits the longest side, so check the real width of portrait images), download the result and repeat. Rename the files with the width in the name so that you can keep track of them. Use the same quality for all versions, typically 75 to 80.

You do not need a version for every possible screen. Three or four steps keep the maximum waste low, and more steps add files without much benefit.

The picture element for formats

The picture element lets you offer different formats, so that browsers that support a newer format can use it. The browser goes through the source elements in order and takes the first type it understands; the img element at the end is the fallback and carries alt, width and height.

<picture>
  <source type="image/webp" srcset="photo-1280.webp 1280w, photo-1920.webp 1920w" sizes="700px">
  <img src="photo-1280.jpg" width="1280" height="853" alt="Description">
</picture>

Today, WebP is supported by all major browsers, so for many sites a single WebP is enough. The picture element is mainly useful when you want to add AVIF, or when you must support older software.

Lazy loading

The attribute loading="lazy" on an img element tells the browser to delay loading the image until it is close to the visible area. For long pages with many pictures, this saves data and makes the first view faster. It is supported by current browsers and needs no JavaScript.

Use it for images that are further down the page. Do not use it for the image at the top, such as a hero image, because that image should load as early as possible. Lazy-loading the largest visible image delays the Largest Contentful Paint, one of the Core Web Vitals, and makes the page feel slower.

Other helpful attributes

Always set width and height on images, so that the browser can reserve the correct space and the layout does not jump when the picture arrives. The browser uses the two values to calculate the aspect ratio, even if CSS scales the image. For the main image, the attribute fetchpriority="high" tells the browser to treat it as important. The attribute decoding="async" allows decoding without blocking other work.

Remember the alt attribute: it describes the picture for people who use screen readers and for search engines, and it is shown if the file cannot be loaded.

Check that it works

Open the browser's developer tools, go to the Network panel, and reload the page at different window sizes. You should see different files being downloaded. Check the transferred size of each image and compare it with the display size. If a phone-sized window downloads the largest file, the sizes attribute is probably wrong.

Fixing images in a few important places, such as the top of the home page and the most visited articles, brings most of the benefit. Start there.

Putting it together on a real page

Imagine a blog post with a header photo and four pictures in the text. Create the header at three widths, 640, 1280 and 1920 pixels, and the text images at two widths, 640 and 1280. Compress them all at a quality of about 75 to 80. That is eleven files, produced in a few minutes with the batch function and the ZIP download.

On the page, the header uses srcset with sizes, width and height and, because it is the main image, no lazy loading but fetchpriority set to high. The four text images use srcset and loading set to lazy. The result is a page where each visitor downloads only what their screen needs.

Create the image sizes you need for srcset with the free image compressor.

Open the image compressor