Image lazy loading – How to implement it with Javascript 1.9k Views Sunday May 17, 2020 | Filip Kunjadić - Ćulibrk

Image lazy loading – How to implement it with Javascript

Image lazy loading is becoming more and more popular nowadays. In other words, Google has implemented a website speed score into its search result index. Therefore we should optimize our websites! You can find more about it here.

Now, what does "lazy load" even mean? To be specific, by "lazy load" I mean loading images AFTER your website page is loaded. It might seem a bit hard to implement, but trust me - it is not hard at all!

Image default load mechanism

Once you write your html code image usually looks something like this:

...
<img src="/images/awesome-image.jpeg" alt="This image rocks!"/>
...

The image is going to load together with your page. And there you might see a problem. Your page will not finish loading until all images in your HTML are loaded into your browser. Imagine having a really long page with many diagrams, but once the page loads visitors will see only the first 1400px of your webpage. And we don't want that! Luckily there is an easy solution to this problem!

Image lazy load mechanism

Now we are going to change things a bit in order to achieve a better speed score. The first thing is to change all image tags to this:

...
<img src="/images/loading.jpg" data-src="/images/awesome-image.jpeg" alt="This image rocks!"/>
...

Why is the image source pointing to another image? It is simple, you need to have one small image that will load together with the page so that the user knows that image will be displayed there later on. That is why you need the "loading" image instead of every image for the initial page load.

Now comes the fun part! Lazy loading the image itself! To implement this, you just need to copy this at the bottom of your page in the script tag and you are done!

window.onload = (event) => {
    var images = document. getElementsByTagName("img");
    for (var i = 0; i < images.length; i++) {
        images[i].setAttribute('src',image.getAttribute('data-src'));
    }
};

Now, let me explain how it actually works! Once the page loads our anonymous function will execute.

var images = document. getElementsByTagName("img");

This line will get all the images from HTML and load them into variable named images.

for (var i = 0; i < images.length; i++) {
    images[i].setAttribute('src',image.getAttribute('data-src'));
}

Now we will loop through all images and set "src" attribute value to "data-src" value which will make our browser load the image.

How to lazy load some images and not the others?

In case that you need to implement lazy load to just a couple of images you can create similar function:

window.onload = (event) => {
    var images = document. getElementsByClassName("lazy-load");
    for (var i = 0; i < images.length; i++) {
        images[i].setAttribute('src',image.getAttribute('data-src'));
    }
};

And in this case, your HTML should look like this:

...
<!-- Image will be loaded after the web page is fully loaded -->
<img class="lazy-load" src="/images/loading.jpg" data-src="/images/awesome-image.jpeg" alt="This image rocks!"/>

<!-- Image will be loaded together with the web page -->
<img src="/images/awesome-image-2.jpeg" alt="Awesome Image"/>
...

Using font icons and CSS transitions instead of loading image

If you want to avoid loading any image on page load, you can easily use font icons in order to show "loading" segment! In this example I will be using bootstrap icons and transitions.

<div class="post-image-holder">
    <div class="text-center pt-4 loader">
        <div class="spinner-border" role="status">
            <span class="sr-only">Loading...</span>
        </div>
    </div>
    <img class="rimage mb-0 d-none" src="/images/1x1.png" data-src="/images/myimage.jpeg" alt="My Image"/>
</div>

The script will look similar but will now hide an element and show another element.

window.onload = (event) => {
    var images = document.getElementsByClassName("post-image-holder");
    for (var i = 0; i < images.length; i++) {
        var loader = images[i].getElementsByClassName('loader')[0];
        var image = images[i].getElementsByClassName('rimage')[0];
        image.setAttribute('src',image.getAttribute('data-src'));
        image.classList.remove('d-none');
        loader.style.display = 'none';
    }
};

For these purposes, we are loading an image that is 1x1 pixel and we are replacing it with a real image. But before we display our real image, we are showing the loading element. Why are we loading image that is 1x1 px? Some browsers still load all the images (even the once that are not displayed) and we want to avoid loading large images before the entire page is loaded.

Conclusion

In order to achieve a high score on Page Speed Insights, it is mandatory to lazy load images. There are other techniques as well, but personally I find this one to be the easiest!

In case you are interested in reading more, you can always learn how to implement a post view counter in WordPress!