Lazy load images – Javascript

Lazy load images means loading images on websites asynchronously. Lazy loading is technique that defers loading of non-critical resources at page load time. Instead, these non-critical resources are loaded at the moment of need. Where images are concerned, “non-critical” is often synonymous with “off-screen”. If you’ve used Lighthouse and examined some opportunities for improvement, you may have seen some guidance in this realm in the form of the Offscreen Images audit.

Intersection observer API

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport.

We are going to use 2 images. One will be displayed on top and second will be at the bottom of page. You have to scroll a lot to see the second image. Now you will see that the second image will only be loaded once the user scrolled to the second one. So this will decrease the page load time and hence improves the performance of your website.

First create 2 image tags and give class attribute to access it in Javascript and data-src attribute. It is a custom attribute which we can use to get the actual path of image. DO NOT use src attribute as it will actually load the image, which we do not want. Give both images width as 100% so they will be completely visible inside the browser window.

<!-- Displaying first image -->
<img data-src="image-1.jpg" class="image" alt="1"><br>

<!-- Displaying second image but at bottom -->
<img data-src="image-2.jpg" class="image" alt="2" style="margin-top: 1000px;">

<!-- Image should not overflow the window -->
<style>
	.image {
		width: 100%;
	}
</style>

Load image when scrolled

Then we create a built-in intersection observer which will be called automatically when page is scrolled and will return the items which are visible. We can check if each item is intersection (inside the browser window). We will get the data-src attribute and place it as src attribute, so in this way it will be loaded asynchronously. Once an image is loaded we do not want it to be loaded again, so we will disable it from observing again by calling the unobserve(item) method.

<script>
	// IntersectionObserver is a built-in javascript object
	var observer = new IntersectionObserver(function (items, self) {

		// Loop through all visible items
		for (var a = 0; a < items.length; a++) {

			// Check if item is in visible area of browser
			if (items[a].isIntersecting) {

				// Debug the img tag
				console.log(items[a].target);

				// Get image data-src (custom) attribute
				var src = items[a].target.getAttribute("data-src");

				// Load the image
				items[a].target.setAttribute("src", src);

				// Should not call this function for same image again
				self.unobserve(items[a].target);
			}
		}
	});
</script>

At this point if you run the script, nothing happens. Because we havn’t tell it which items needs to be observed. Since we have given a class attribute to images so we can get all images having that class. Loop through each image and set it to be observed by observer using it’s instance.

<script>
	// Get all images
	var image = document.getElementsByClassName("image");

	// Loop through each image
	for (var a = 0; a < image.length; a++) {
		// Make it observable
		observer.observe(image[a]);
	}
</script>

Conclusion

There are also many libraries available which can do the lazy loading for you. But nothing gives more control than writing your own code. So using this Vanilla JS way you can use intersection observers to lazy load images you want as per required.

[wpdm_package id=’197′]

Leave a Reply

Your email address will not be published. Required fields are marked *