paint-brush
Optimizing Images in a Few Stepsby@evgeniikravtsov
589 reads
589 reads

Optimizing Images in a Few Steps

by Evgenii KravtsovDecember 23rd, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

This article will be devoted to optimizing images on the site, both obvious and not-so-obvious. In a few steps, we will try to optimize our images so that our site works as quickly and optimally as possible.
featured image - Optimizing Images in a Few Steps
Evgenii Kravtsov HackerNoon profile picture


This article will be devoted to optimizing images on the site, both obvious and not-so-obvious. In a few steps, we will try to optimize our images so that our site works as quickly and optimally as possible.

Introduction

To begin with, we will create a simple html file, where several images are located one below the other. We will use this html file for improvement.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body { display: flex; flex-direction: column; align-content: center;}
        img { width: 100%; height: 100vh;}
    </style>
</head>
<body>
    <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670949584/image_1_mvfm6d.jpg" alt="Mountain" />
    <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670949606/image_2_hhawzv.jpg" alt="Mountain" />
    <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670949623/image_3_qt385v.jpg" alt="Mountain" />
    <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670949650/image_4_rtxm8s.jpg" alt="Mountain" />
    <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670949666/image_5_e6gjpo.jpg" alt="Mountain" />
</body>
</html>


For this example, I have pre-loaded 5 images to the cdn service, later we will discuss why this is worth doing.

In this file, we simply displayed 5 images that are stretched to the full width of the screen and the height of the viewport. If we open the file in the browser and look at the network tab, we will see that all the images are loaded immediately, although at the very beginning only the first one is displayed, and all the others remain outside the viewport.

Optimisation

The first thing we can do is not to request all the images at once, but only those in the viewport or close to it. This technique is called lazy load. As we can see, almost all modern browsers support this attribute. To enable it, we must register for images.

loading="lazy"

After adding this attribute, we see that only 3 images were loaded instead of 5, thus we significantly increased traffic savings, which is very important for mobile devices!

Next, I would like to pay attention to the size and format of the images. They are very large and not modern format. Let's fix it! I used the Squoosh service to change the images to the more modern Avif and WebP formats, as for browsers that do not support them, we will leave the fallback to the old image format, but also pass through the image optimization service.

Summing up, the approximate winnings with the same in each format:

  • Avif - 50 to 80 percent
  • Webp - 40 to 60 percent
  • Jpeg - 20 to 40 percent

The html currently looks like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body { display: flex; flex-direction: column; align-content: center;}
        img { width: 100%; height: 100vh;}
    </style>
</head>
<body>
    <picture>
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695023/image_1_bvkbca.avif" type="image/avif">
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695023/image_1_m03zc8.webp" type="image/webp">
        <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670695023/image_1_optim_auu7xi.jpg" alt="Mountain" loading="lazy">
    </picture>
    <picture>
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695610/image_2_ekp1uv.avif" type="image/avif">
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695610/image_2_ngrhao.webp" type="image/webp">
        <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670695610/image_2_optim_xlxrp0.jpg" alt="Mountain" loading="lazy">
    </picture>
    <picture>
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695732/image_3_fsogof.avif" type="image/avif">
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695732/image_3_oibhob.webp" type="image/webp">
        <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670695732/image_3_optim_vgkjae.jpg" alt="Mountain" loading="lazy">
    </picture>
    <picture>
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695822/image_4_km1zpx.avif" type="image/avif">
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695822/image_4_ipe9qy.webp" type="image/webp">
        <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670695809/image_4_optim_fc4g0x.jpg" alt="Mountain" loading="lazy">
    </picture>
    <picture>
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695909/image_5_qek5an.avif" type="image/avif">
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695909/image_5_sf5qvf.webp" type="image/webp">
        <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670695909/image_5_optim_dre3sn.jpg" alt="Mountain" loading="lazy">
    </picture>
</body>
</html>

As a result, the Network tab of the browser looks like this:

Next, we would like to make sure that at different screen resolutions, we request different images, since it is not optimal to always request images with the maximum resolution. To do this, we can use the srcset attribute. Namely, to register there links to images with smaller sizes for smaller screen resolutions.

Example:

    <picture>
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/c_scale,w_768/v1670951731/image_1_bvkbca_ahioi4.avif 768w, https://res.cloudinary.com/deysgcxss/image/upload/v1670695023/image_1_bvkbca.avif" type="image/avif">
        <source srcset="https://res.cloudinary.com/deysgcxss/image/upload/v1670695023/image_1_m03zc8.webp" type="image/webp">
        <img src="https://res.cloudinary.com/deysgcxss/image/upload/v1670949584/image_1_mvfm6d.jpg" alt="Mountain" loading="lazy">
    </picture>

Result:


I want to note that what I did manually for a long time has been able to modern cdn return services. It is also possible to host a self hosted solution like imgProxy.

Conclusion

As a result, we used almost all modern image optimization techniques, which allowed us to significantly reduce the number of kilobytes downloaded for the site, which is very important in the modern world of mobile devices!