Website optimization using lazyloading Images in JavaScript
Website optimization is very important when it comes to building a product that will be shipped out for people, customers, or users to use, you don’t want to end up putting more energy to work on a particular product or projects and at the end of it, no one visits you website in a day or maybe two days.
The goal of this article is to improve the performance of websites, User’s experience, and page loading speed by lazyloading images.
Before we start, let look at what is website optimization?.
What is website optimization
Website optimization is the process of using advanced strategies to improve website performance when users are on your website, Increase the website visibility on search engines, and improve its user experience.
The first thing you will always have to look out for when optimizing your website is SEO (search engine optimization). That is optimizing your website to be among the top first website when users search on content relating to your website and to be able to find your website in the easiest possible manner.
Important of website optimization
Website Optimization helps you gain your visitors’ trust, it helps you build a relationship, it helps you sell your product without paying for an advertisement on any social media platform.
I am sure we now understand what website optimization is and it’s important. Now the question is how can lazyloading images on our website help us achieve website optimization?. That is what we are about to find out.
With out wasting time let us look at what is lazyloading?.
What is lazy loading?
Lazy loading is the practice of delaying load or initialization of resources or objects until they’re actually needed to improve performance and save system resources.
Every website you see today has one or more images on it, if it does not appear on the hero page, it will appear on the footer, and optimizing how the images are loaded can improve the website delivery speed and user experience on your website.
Techniques use to Implement Lazyloading
There are several technical approaches to lazy loading images:
- Inline
<img>
tags, - The Intersection Observer API
- The CSS background-image property
For the purpose of this article, we are focusing on the use of Intersection Observer API
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.
What that means is that, it delays a targeted element from loading until when that element is needed or it is at the viewport.
Setting up the project
For the purpose of this article we are be consuming Unsplash API.
Create a .html file and write the code below:
<div class="mt-4" id="display">
</div>
The code above is a div element that has an id of display. Inside the div element is where we are going to display the images that we are fetching from Unsplash API.
Create a .js file and write the code below:
function loadImage(){
fetch(`https://api.unsplash.com/photos/?page=1&per_page=21&client_id=your_id`)
.then(response => response.json())
.then(arrayOfObjects => {
})
.catch(err => {
console.log(err)
});
};
loadImage();
In the above code, we declared a function called loadImage(), and what the function simply does is to fetch data from the Unsplash API whenever it is been called.
Now, we are going to loop through the data.
arrayOfObjects.forEach(obj => {
let { urls, id, alt_description, color, user} = obj;
document.getElementById('display').innerHTML += `
<img alt="${alt_description}" data-image="${user.profile_image.small}" data-
full="${urls.full}" data-lazy="${urls.small}" data-toggle="modal" data-target=".bd-example-
modal-xl" style="background-color:${color}; font-size:12px;" onclick="myFunction(this)"
class="lazy-loading"> `;
});
In the above code, we first loop through the responses using forEach(), then we use document.getElementById() to get the id of the element we created inside .html file and we use .innerHtml property to sets the response to the <img src=””> tag.
If you save and load the .html file on your browser you can see the image displayed on the website.
If we inspect the page and open the network tab we will see the 21 images loading at the same time even when we have not scrolled to their viewport and if it was a website that has other information that needs to be passed to the user when this image is loading, the user has to wait until the images are fully loaded before it can allow the user to see the information.
But we can manipulate how this images are going to be loading so that user can access other information on the site.
Using the Intersection Observer API
Inside our .js file, we are going to create a function call lazyloading(). But before that let document.querySelectorAll() the class attribute that we passed on the img tag.
lazyTargets = document.querySelectorAll('.lazy-loading');
lazyTargets.forEach(lazyTarget => lazyLoad(lazyTarget));
In the above code, we declared a let variable called lazyTarget and set the values as document.querySelectorAll(). And the document.querySelectorAll get the list of all the element inside the .html that matches the class attribute that is been passed to it. And the class attribute we are targeting is the .lazy-loading class that we passed on the img tag so that we can be able to get all the images that were fetched from the Unsplash API.
After that we use .ForEach() function to loop the through the images since it not just one image that we are targeting, and there we called the lazyloading() function and we passed the object that holds all the images.
Now let move further with observing the images.
function lazyLoad(target) {
const obs = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
const src = img.getAttribute('data-lazy');
img.setAttribute('src', src);
img.classList.add('fadeIn');
observer.disconnect(entry.target);
}
});
});
obs.observe(target);
}
In the above code, we declared a function lazyLoad(),
We created constant variable call obs and set the value as new IntersectionObserver. The new IntersectionObserver takes two arguments, a callback function, which is the entries, and optional objects which observe.
The observe is used to specify the conditions for when the callback function is triggered.
The callback receives a list of IntersectionObserverEntry
objects and the observer.
We used .forEach to loop through the list of the entries received by the callback function and each of the entries includes one entry that is targeting a reporting change in its intersection status.
We also set an If condition to check if the entry is intersecting.
Inside the if condition we declared a constant variable img set the value as entry.target and we get the attribute of the targeted image data-lazy. The data-lazy attribute holds the src of the images that are fetched from Unsplash API, and we replace the data-lazy with src attribute. After that, the observe disconnect entry.target and set it to observe the next images that will appear on the browser viewport.
If we refresh the browser and open the network tab we will see that it only the images that are on the viewport that are been loaded other imges are pending and loads only when they are visible to the users or if user scroll to see them.
After implementing the lazyloading on our image we notice that the time it took to load the website and the time it take to load the website when we have not implemented the lazyloading is different. It was more faster to load because we are not fetching the 21 images at the same time.
Conclusion
In this article where able to understand what is website optimization and the importance of website optimization, we also look at how we can implement lazy loading on the images on our website and the use of intersection observer API.
If you find this article helpful don’t forget to share it.
The source code of this app is on Github and the demo of the app