Why bother loading all the images if users still can't see those yet?

Actually, it even makes their user experience worse as the website is slow down by loading a bunch of unnecessary files and *cool animations*

So what is the solution to this? INTERSECTION OBSERVER !!

Okay, what is that?

The Intersection Observer API provides a way to asynchronously observe changes… OOPS!, you might have mistaken this website with MDN. I won’t explain bunch of information again that both of us are too lazy to read. Haha.

so let’s just start and do it.

Let’s take a look at this starter codepen.

When the website is loaded, the images are immediately load also. And at that time, you can’t even see the first image yet.

Image in a image block

Let’s use intersection observer to implement lazy load to the images.

1) Change your image src attribute to be data-src (it is custom attribute you can name anything, even banana)

2) Firstly, let’s just select all the images and get the image urls that need to be loaded later.

const images = document.querySelectorAll('img');

// Loop through the images 
images.forEach(image => {
	const imageURL = image.getAttribute('data-src');
})

3) Let’s add IntersectionObserver and see what are the parameters inside the callback function.

const images = document.querySelectorAll('img');

// Loop through the images 
images.forEach(image => {
	const imageURL = image.getAttribute('data-src');
	
	const observer = new IntersectionObserver((entries, observer) => {
			console.log(entries);
		//   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
	}, {});

	observer.observe(image); 
})

The first parameter is the list of entries and second one is the observer itself. We don’t need to use second one yet.

In the current situation, we only care about isIntersecting value from entries. If isIntersecting return true, the element is already intersected and it is in the viewport.

4) So if isIntersecting equal to true , let’s load the related image by updating src .

const images = document.querySelectorAll('img');

// Loop through the images 
images.forEach(image => {
	const imageURL = image.getAttribute('data-src');
	
	const observer = new IntersectionObserver((entries, observer) => {
			entries.forEach(entry => {
					if (entry.isIntersecting) {
							// Change the image src to imageURL
							image.src = imageURL; 
					}
			});
	}, {});

	observer.observe(image); 
})

You have successfully implement the lazy loading for the images and have the basic understanding for intersection observer. Here is the final code for your reference.

https://codepen.io/starryskadi/pen/mdgJEJq

Happy Hacking!

Bonus Tips, you can add the placeholder image in src in the image to show the user that it is still loading.

Copyright © 2024, JUST ANOTHER WEB DEV.