DEV Community

Discussion on: How to lazy load images in html with pure Javascript?

 
thomasverleye profile image
Thomas Verleye

As I already stated, I'm just suggesting it :-) As I'm trying to say, it's a progressive enhancement. Your website won't be broken on the 25% which doesn't support loading="lazy". The opposite can be said about JavaScript code that doesn't work, if this code does not work or fails to kick in user won't be able to see your images.

Even with a throttle (timeout) this wil slow up low end devices. I would suggest you use passive listeners.

Also, I have taken a closer look at your code and the forEach function is not supported in IE11 and lower, so IE users won't be able to see the images. I'd suggest you use a basic for loop for this.

Thread Thread
 
mfurkankaya profile image
Furkan KAYA

I think you're right about IE 11 and forEach but it can be handled with transpilers. I'm saying that because of many projects are using. If someone uses these lines of code with vanillajs, people won't see the images on IE11 and lower. If you ask me, lower versions are don't matter anymore but IE11 is still worth. We get 5% of our traffic from IE11.

Thread Thread
 
thomasverleye profile image
Thomas Verleye

Transpilers will indeed resolve this, but not all users will be using transpilers who are reading these blog posts.

Nothing wrong with just writing it as a basic for-loop though, then it's completely vanilla and users can simply copy pasted it.

I took the opportunity to improve the code to:

document.addEventListener('DOMContentLoaded', function () {
    var lazyloadThrottleTimeout;

    function lazyload() {
        if (lazyloadThrottleTimeout) {
            clearTimeout(lazyloadThrottleTimeout);
        }

        var lazyloadImages = document.getElementsByClassName('lazy');
        if (lazyloadImages.length < 1) {
            return;
        }

        lazyloadThrottleTimeout = setTimeout(function () {
            var scrollTop = window.pageYOffset;
            for (var i = 0; i < lazyloadImages.length; i++) {
                if (lazyloadImages[i].offsetTop < window.innerHeight + scrollTop) {
                    lazyloadImages[i].src = lazyloadImages[i].dataset.src;
                    lazyloadImages[i].classList.remove('lazy');
                }
            }
        }, 20);
    }

    document.addEventListener('scroll', lazyload);
    window.addEventListener('resize', lazyload);
    window.addEventListener('orientationChange', lazyload);
});
Enter fullscreen mode Exit fullscreen mode
  • I've added a basic for-loop instead of the forEach.
  • Reselected the Lazy Loading images each time the event occurs. This way it's more performant and can't break less. You have to know that sometimes other scripts will remove one of these images and then your script will throw an error. OR if you have inserted new images which should lazy load a reselect of the images would improve that.
  • I would suggest you don't remove the eventlisteners at all if you'd like to load newly added images. The removal of these listeners in the current script didn't work anyway because the array doesn't remove the images that are already lazy loaded :-)
  • As you can see the throttle is not needed if your array is empty so I have early returned the function so no unnecessary timeout have to run.

That being all said, I still recommend using loading="lazy" for the sake of compatibility ✌️