Contents
Intro
They say a picture tells a thousand words. It certainly costs a thousand words when it comes to performance!
Images tend to be quite large files, so take a while to load. They also block rendering so they have to complete before content further down the page can load.
But there is hope! We can make images lazy and get out the way of the rest of the page with some simple attributes!
First thing first, make sure your images are as small as possible in the first case. I'd highly recommend Squoosh by the Chrome team which you can use to optimise the size of your images.
Convert them to more modern formats like webp which can save up to 26% of file size just by changing the file type!! Webp has fairly good browsers support now too.
Images
Here's a current image on a website:
<img src="some_image_file.png" />
We can improve the loading of this image with a few attributes, like so:
<img src="some_image_file.png" loading="lazy" decoding="async" alt="A Description of the image" />
Easy!!
Lets dig into those attributes.
Loading
It has wide browser support now, and if the browser doesn't support it, it will just be ignored, so no excuse not to add it!
It can have the values of eager
or lazy
.
Eager is the default value, meaning it will load the image immediately regardless of if the user can currently see the image.
Lazy allows the browser to decide when to load the image, which is will do when the user is nearer the content. Meaning we don't have to load a full page of images straight away, only the ones we can see immediately.
Decoding
This is supported across all browsers.
This gives the browser a hint on how you want your image to be decoded, either synchronously or asynchronously. Either getting in the way of the rest of your content or not.
Alt
This doesn't impact loading performance. But please use it! π
It takes very little effort to add and helps make your site more accessible!
The best way to come up with the value is to imagine you are describing the image to your friend over the phone, how would you do it.
This is exactly how the alt attribute functions to screen readers so please use it!
Background Images
Background images are a bit more tricky to be lazy loading.
Firstly I would really try not to use background images as they aren't great for accessibility, so if at all possible use a normal image element.
If you absolutely can't use a normal image. Then you'll have to resort to using JavaScript to only display the image when its near to viewport.
This can be achieved with the Intersection Observer, there is a great example of that on the web.dev site which I would recommend if you absolutely can't use the image element.
Summary
In summary, these 3 attributes improve the performance of your website with minimal effort!
There is no browser support issues or any reason not to use them, so add them to your images now!
These attributes also work is you are using a picture element, just set them on the image element as normal.
Here's an example of using a picture element for switching images based on dark mode or not.
<picture>
<source srcset="/images/linkedin-white.webp" media="(prefers-color-scheme: dark)" />
<img class="linkedin" src="/images/linkedin.webp" alt="LinkedIn Profile" loading="lazy" decoding="async" />
</picture>
They also work is you are using a image element, with multiple sized images via srcset
attribute.
Add these 3 simple attributes to your images right now!
Happy Building!
Top comments (13)
The lazy loading feature is the best attribute ever for images. A simple responsive image solution is to combine
loading="lazy"
with CSS media queries to setdisplay: none
on image elements based on screen size. This allows you to tell the end user client you whether or not the image should be requested (for<img>
tags) based on screen size. The standard way of doing this would be to use thesrcset
attribute or the<picture>
tag but I found this solution to be much simpler and just as effective.As for the decoding attribute, am I right to assume that it doesn't do much if we set loading="lazy"? Since everything else would already be loaded in this case, it won't matter whether the image is decoded synchronously or asynchronously right?
I'd still add the decoding attribute for browsers that don't support loading=lazy and you might still get performance improvements for large images.
I think a nicer way to do your responsive image solution would be to set the images as
source
s inside a picture element like this example as then you don't have to have all the media queries in your styles, they can be in the picture html. It's also then using the inbuild browser functions.Please correct me if I'm wrong, but the limitation with using the
<picture>
element is that you can only tell it what image to use, you can't tell it to not load any images at all. One hack would be to tell it to load a 1kb image (using some data URI) if you you're not intending to display the image on smaller screen sizes. But that is still a hack/workaround rather than intended functionality.You make a good point about the limitation of loading="lazy" not being supported for all browsers though.
If you are setting display none on the picture if you don't want to see it then it won't load the image, which allows you to do everything you need
When I mean load, I mean that the client sends a network request to download the image from the server.
display: none
hides the image after the client has already downloaded the image, which isn't good for mobile-design as it wastes bandwidth if users are on data instead of Wifi.Most browsers will see the image isn't displayed and not load the image, especially with the attributes mentioned. Is my understanding.
My opinion is using an image as a background is OK, if the purpose is purely decorative, like a pattern. Even then, there might be a way to convert the image into SVG or use a CSS pattern, which would reduce bandwidth, depending on the image. I guess if using an image as a background is absolutely necessary, it's probably possible to include a caption to explain what the image is about.
I find that using alt tags is really helpful also when testing a site, and seeing an image didn't get uploaded. The alt tag helps me know which image it is, rather than hunting down a random image out of hundreds.
And I did not know lazy loading was an attribute for images, but now I will try it out!
Add also width and height so that your images don't become lines in first load until your css determined their size.
This is old school shtuf
Yesss, I'm hoping folk are already sizing their images π
Old School is often the best! :D
Thank you for the informative post! Bookmarked, and I have a free hour tomorrow that I'll spend making my portfolio images better.
Bookmarked π
good to know
Very useful π