Performant image loading

The basics and a few tips for faster image loading.

  • Tags: Web Development, Performance
  • Last updated: 

Loading images is what we do. Oftentimes. How to do it well is a different thing. Here are a few tips.

The basics

Add width, height and alt attributes

Providing width and height will provide the browser with the necessary information to prevent layout shifts. Getting them is sometimes harder to do, because you’ll either need to set them manually or get them automatically at buildtime or from an API.

Check my deno script at the bottom to see how you can do it yourself.

Providing alt attributes is great for accessibility. That’s your main concern. This will also make for better SEO, so that’s neat.

Create a sourceset and provide sizes

Sourceset combined with sizes will help the browser load the approriate image based on the viewport width.

Generating sourceset is fairly straight forward: Use an online converter or do it yourself. It’s just resizing images, creating the filenames and dumping them into a single string, that looks like this:

/content/images/sources/2021-12-31_flur_neues-namensschild_480.jpg 480w,
/content/images/sources/2021-12-31_flur_neues-namensschild_800.jpg 800w,
/content/images/sources/2021-12-31_flur_neues-namensschild_1280.jpg 1280w,
/content/images/2021-12-31_flur_neues-namensschild.jpg 1440w

The format is: {imagePath}{imageName}{containerWidth*},

The container width is set with the sizes attribute, which looks like this:

(max-width: 480px) 480px, (max-width: 768px) 768px, (max-width: 1280px) 1280px, 1440px

Format is: (max-width:{width}): {containerWidth}.

This practically means: Up to {width} this container will be {containerWidth} wide.

Note: You can use different media queries here, too.

Adding lazy loading and async decoding

Most browser now natively support loading="lazy", which loads images when they are close to the currently shown viewport. Your page will load faster and load images as needed.

Careful: You don’t want to lazyload your “above the fold” image. Set them to loading="eager" instead, so your page will look nice when loading for the first time

decoding="async" will do something similar: Defer the image decoding to a later point in time, so your page can load even if the image is not yet decoded.

A few more tips

  • Cropping your mobile images can be very helpful to reduce the file size while keeping what you want to show. Basically crop your image around what you want to show in a vertical orientation. (Credits go to u/Citrous_Oyster).
  • Resize and optimise your images beforehand. You can do that in your build, manually or through your image cloud service. Only load images in the sizes you actually need and set the quality to around 70% is a good starting point.
  • Load graphics as svg: If you have them, load your logos and graphics as SVGs. They’re smaller in size.
  • If you use a different image host, it might be beneficial to preconnect to that service using: <link rel="preconnect" href="{yourService}" />
  • While you’re at it: You can also preload your header image, if you have one: <link rel="preload" href="{imagePath}" as="image" crossorigin="anonymous">

I’ll add to this, when I learn more.