Lazy loading images in 2024
Tags: lazyloading, html, picturetag, webdev
Published: 2024-01-12 15:08:36

A couple of years ago I did a post about my method for lazy loading images with (vanilla) javascript. Things have changed much since, for the better :-)

Now we can control lazy loading easier and with less code than ever. You have probably heard of the “loading” attribute, but have you also dived into the “decoding” attribute? Below is a little example of how I often set up images these days.


```
<!-- This image is above the fold-->
<picture class="lazy">
  <source srcset="/Assets/Images/1920.png" media="(min-width:1600px)" width="1920" height="1080">
  <source srcset="/Assets/Images/1280.png" media="(min-width:1000.5px)" width="1280" height="720">
  <img src="/Assets/Images/640.png" width="640" height="360" alt="" fetchpriority="high" draggable="false">
</picture>
<!-- This image is below the fold-->
<picture class="lazy">
  <source srcset="/Assets/Images/1920.png" media="(min-width:1600px)" width="1920" height="1080">
  <source srcset="/Assets/Images/1280.png" media="(min-width:1000.5px)" width="1280" height="720">
  <img src="/Assets/Images/640.png" width="640" height="360" alt="" loading="lazy" decoding="async" draggable="false">
</picture>
```


There are a few things to notice:
For images above the fold, Google now [recommends](https://web.dev/articles/optimize-lcp) using fetchpriority=”high” and no “loading” attribute. This speeds up the Largest Contentful Paint metric and helps your website load faster.

For images below the fold, remove the “fetchpriority” attribute and add loading=”lazy” instead. This really simple method now lazy loads your images, no javascript is needed (unless you want to control an animation, maybe fading in the image).

If you also add decoding=”async”, you are telling the browser to control when and where the decoding happens. There are discussions about the impact of this, but it’s probably better to do this than not.

The above code is really simple, but remember you can [control the (source) “srcset” even more detailed](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) with high DPI images etc.

A while ago I did a lot of research to find out if I should use the “picture”, or “img” element. I ended up with “picture” because of Art Direction purposes: often the mobile image isn’t the same aspect ratio as the desktop, so I need more individual control of the sources. Read more about this here and here. The “img” tag is still great for many things, so don’t completely move away from it.

Another great thing about this new(er) method is that you don’t need the aspect ratio (padding-top on parent container) trick anymore. The image has the correct size instantly, which makes for faster rendering and less code.

The browser support for modern lazy loading is [really good](https://caniuse.com/loading-lazy-attr), so go ahead and make your life easier :-)

As a [creative freelance front-end developer](https://iliketoplay.dk/) I often try to optimize my methods, utilities and frameworks. It’s important though that I always consider all users and not only the people with new updated computers and devices. The above method is not new, but in my opinion it’s only now that the market is ready (unless you have clients who don’t care about old computers etc.).