How to Lazy Load Images/videos/other heavy contents in javascript?

Vishal Gupta
3 min readMay 8, 2019

--

Before we deep dive inside lazy loading of images, first we need to have proper knowledge of lazy loading. We should have the answer that what exactly is lazy loading?

Surely many of you have already heard that Google Chrome is going to add Lazy Loading in a native way with HTML tags, for images and iframes.

What Lazy Loading basically means is not to load the content of these images or videos or any such content that is going take some time in loading, until the user does not have them in the field of view. In this way, an image(for this article) located at the end of the web page will never be loaded if the user does not reach that point. With this solution, we save loading time and gain speed.

Our HTML look and feel

Below is our index.html file. It just has a title, a loading spinner and an empty div where we'll put all the images from the API.

<!-- index.html --><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Lazy Loading Images</title>

<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Lazy Loading Images</h1>

<!-- Images Container -->
<div id="imagesContainer"></div>

<!-- Loading spinner -->
<div class="lds-roller" id="lds-roller">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

<!-- Our custom JS code -->
<script src="main.js"></script>
</body>
</html>

At this point our page is empty, lets load our images now in a lazy loaded way and henceforth create our main.js file for compiling the js code.

NOW FROM HERE THE MAGIC BEGINS

window.onload = () => {
// Get 30 random images
fetch('https://picsum.photos/v2/list?limit=30')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
// Call the createImages function to generate the HTML code
createImages(myJson);
// Remove the loading spinner
document.getElementById('lds-roller').remove();
})
.catch(err => {
console.log(err);
});
};

This first function will be triggered ones the window is ready. We use the fetch API or else we can also use axios api too to get the images from an external API. (Axios and Fetch have their own documentations on https://www.npmjs.com/package/). This API response us with a JSON file containing all the url's to the images. With this url's we can now create our HTML code.

function createImages(imgs) {
for (let i of imgs) {
// Create an image HTML tag with js DOM
const image = document.createElement('img');
image.setAttribute('data-lazy', i.download_url);
image.classList.add('lazy-loading');
document.getElementById('imagesContainer').appendChild(image);
}
// Sets an observer for each image
lazyTargets = document.querySelectorAll('.lazy-loading');
lazyTargets.forEach(lazyLoad);
}

Note that we’re not setting the src attribute of the images. We're creating a data-lazy attribute to uniquely identify the lazy component. This way, the images don't request any data when they are created. Now let's do the lazy-loading function. This function will use the intersection observer API to know when each image is on the view. For “intersection-observer” you can refer to the documentation of npm on link https://www.npmjs.com/package/intersection-observer. Then it'll replace the src attribute with the data-lazy one.

function lazyLoad(target) {
//making use of IntersectionObserver package
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();
}
});
});
obs.observe(target);
}

You can make this pretty by making a .html for outlook and .css file for styling purpose.

For codepan code please refer https://codepen.io/vishalvishalgupta/pen/NVqQPG

Thanks for reading… HAPPY JAVASCRIPT….

--

--

Vishal Gupta
Vishal Gupta

No responses yet