Wednesday, June 21, 2017

Lazy load images with Javascript depending on the user view window

In this blog post, I will describe how I added lazy load of images to my website. If you have a page with many images, it is very useful to not load all images at page load but to load the images on demand. This is especially useful for people with bad internet connections or people who visit your page on mobile devices.

The first step is to load a spinner symbol instead of the actual image, but to write the image in the data-src property so that the HTML looks something like this:
<img class="lazy_load_image" src="/static/spinner.gif" 
data-src="{{ path_to_image }}" alt="{{ image_name }}" 
style="width:300px;hight:400px;">
With this markup, only the spinner image will be loaded on page load and you should, of course, make sure that this is a small image, but there are many examples you can find online.

Now after page load, we want to load the images and we do this with Javascript by adding an event listener
// This code lazy loads the images in the viewport after the page load
window.addEventListener('load', function(){
    load_lazy();
}, false)
The load_lazy() function just writes the data-src property of the HTM tag above into the src property for all images which are in the viewport:
// This function loads all images in the viewport
function load_lazy(){
    // we expand the viewport by 200px
    var images = $('.lazy_load_image').withinviewport({top: -200, bottom: -200});
    for(var i = 0; i < images.length; i++){
        var image_src = images[i].getAttribute('data-src');
        if(image_src){
            images[i].setAttribute('src', image_src);
            images[i].className -= 'lazy_load_image';
        }
    }
}
For this to work you have to download and include withinviewport.js (bower install within-viewport).
Here I extended the viewport by 200px, just to make sure that the user does not see a spinner forever if less than 50% of the image is in the viewport.

The last step is to make sure that images get loaded if the user scrolls down, which we can do by adding
// This code lazy loads the images in the viewport after scrolling
$(window).scroll(function(){
    load_lazy();
})
This function gets called whenever the user scrolls, and if a new image has entered the user view, it will be loaded by the load_lazy() function.

Hope that was useful. I posted the entire code on GitHub.
cheers
Florian

No comments:

Post a Comment