According to the data from HTTP archive, 64% of a website’s page weight, on an average, is made up of images. With mobile traffic surpassing desktop traffic, it has now become even more crucial to optimize images for different device sizes.
Ideally, you would like to serve images that are resized to match the user’s viewport dimensions. Without a means to do this, you will sometimes have to send a larger image than what is actually required.
This means that the user has to download more data than he should be downloading, which in turn slows down the page load. This is a wastage of time, bandwidth, and money which impacts the overall user experience, and hence, conversions on your website.
Let’s say you want to have a full-width banner on the top of your website. A 1280px wide banner image would work well on a desktop device for this purpose. But the same image is too big to use as a full-width banner on a mobile device which has 320px wide screen.
In short, we want the browser to load the correct image based on:
1. The viewport dimensions
Whether the viewport is 1280px wide or 640px or 320px.
2. The size of the image relative to the viewport
Whether the image occupies 100% of the available width or 50% or 33%. In our example of the full-width banner above, the image occupies 100% of the available width.
Now that we have identified the problem, there are a couple of ways to get the solution:
- Using client hints (DPR, Width, and Viewport-Width) — very less support
- Using srcset
and sizes
attributes of the img
HTML tag — supported by all major browsers
We will talk about the srcset
and sizes
attributes in this article.
Before discussing the actual implementation, let’s talk about what is known to you as a developer at the time of writing the code, and what is known to the browser at the time of actual rendering of the images.
As a developer, you know two things that the browser does not know at the time of triggering image load (which is before the CSS is parsed):
1. The size of the image relative to the viewport
This depends on the layout that you are trying to build on your website as discussed above in the full-width banner example.
2. The URLs of different sizes of the image
Now that you need different images for different viewport dimensions, each image should be accessible individually on a unique URL.
On the other hand, as a developer, you have no clue about the actual viewport dimensions. This is something which is available only to the browsers at the time of actual rendering.
So, if somehow we pass on the two pieces of information that we know as a developer to the browser, then the browser has all the information needed to select and load the appropriate image.
This is what the srcset
and sizes
attributes are all about!
The srcset
attribute tells the browser the URLs of different sizes of a particular image and the width of each image, using the w
parameter
srcset="large.jpg 1024w,
medium.jpg 640w,
small.jpg 320w"
In the above example, we are basically telling the browser that we have 3 image sizes with us. large.jpg
is 1024px wide, medium.jpg
is 640px wide and small.jpg
is 320px wide.
The sizes
attribute tells browser about how the image will be laid out on our website. It uses the length
parameter
sizes="[media query] [length], [media query] [length] ..."
From the list of sizes
specified, the browser goes over each media query until it finds the one that evaluates to true and uses the length
specified against that media query as the final width of the image to be rendered.
Without this additional styling information specified in sizes
, the browser would have had to wait for the CSS to be downloaded and parsed. With the sizes
attribute, we are simply providing this crucial bit of information in advance.
Once the width of the image to be rendered has been identified from the sizes
attribute, the browser selects the most appropriate image from the list specified using the srcset
attribute and starts to load that image.
We have set up a demo page to illustrate the use of srcset
and sizes
attributes using ImageKit’s URL-based transformations. The page can be accessed here.
With ImageKit’s URL based transformation, you don’t have to create and manage different sized assets on your server. You can create them on-the-fly and implement responsive images. All you have to do is identify what all sizes do you need and just write the markup.
Let’s have a look at the code from our example, which demonstrates the use of srcset
and sizes
attributes.
Here, we are providing 3 different image URLs and the width of each image via the srcset
attribute. The three images have widths 500px, 800px and 1024px which is obtained by using the width transformation tr:w-
in the URL.
Then we have used the sizes
attribute to provide the final width of the rendered image. With the value (min-width: 1024px) 1024px, 100vw
we have actually specified two media query and length sets.
The first set states that whenever the viewport width is equal to or greater than 1024px, then the image takes up exactly 1024px. In other cases (i.e. when the viewport width is less than 1024px), then the image takes up 100% of the viewport width (specified using 100vw
).
If you check the demo page and resize the window you will notice:
1. At 400px, the browser uses the image with width 500px
/tr:w-500/responsive_images_srcset_sizes_assets/big/1.jpeg
2. At 700px, the browser uses the image with width 800px
/tr:w-800/responsive_images_srcset_sizes_assets/big/1.jpeg
3. Above 800px, the browser uses the image with width 1024px
/tr:w-1024/responsive_images_srcset_sizes_assets/big/1.jpeg
The browser automatically picks the best image based on actual viewport width, pixel density (and possibly based on bandwidth limitations or user preference).
Notice that while using srcset
and sizes
, you could end up with a huge list of potential source image files, hence you should employ a good strategy to choose breakpoints to keep the markup simple.
This content about responsive images was originally published on ImageKit's medium blog as "How to deliver responsive images across multiple devices"
Please do share your thoughts about this in the comments section below. You can try ImageKit.io by registering for free and implement cross-device responsive images in your project today.