Published on

Image Lazy Loading with Vanilla JavaScript

Last Modified on
Last modified on
Image Lazy Loading with Vanilla JavaScript
Photo by Priscilla Du Preez on Unsplash

Update 4.23.22: I ended up removing lazy load for the body element background images in the index.html, portfolio.html, and contact.html pages, but added lazy load to all the img elements inside all the figure elements. That way, once the body background image for the portfolio.html page started loading, it triggered the loading for the other images. Otherwise, whichever figure element images I did not lazy load, appeared completely collapsed, because they did not initially contain the placeholder images inside the values of their src attributes. And that just looked strange and not the greatest visual UX!

Recently, I changed the images on my example portfolio site for the Web Design I class I am teaching from absolute paths to images under the Creative Commons license to locally installed images inside an images folder. I cropped them all down to 1500x1000 pixels, about double the size of the Creative Commons images, but I was not going to get fancy with using picture elements or srcset elements with different size images for different viewport widths. So at first, I did nothing.

I checked my page performance using Lighthouse. It was abysmal. The audit score was very low for performance.

Subsequently, I had a session with a student, and she told me that all she saw on her screen on my page was the default aqua blue background color, and nothing else. Then I realized that not everyone is going to always have the greatest internet connection, and even on my devices, it was taking a long time for all 15 images to load. I knew then that I had to do something about it.

First I studied the Lighthouse audit details regarding how I could improve my page’s performance. It mentioned using a next-gen image format. Either AVIF or WebP. I looked up both, and WebP’s browser support was much better. So I went with that.

Next, I found a site that transformed jpgs into webp files. I transformed as many as I could until I maxed out my free trial, and then found another site to transform the rest. I also found out however, that I could use Node.js to transform my jpgs into webp files, or I could download a converter on my computer using Homebrew and do it that way. In the future, Node.js seems like the way I would want to go. But that is for another post!

Then I looked into whether there was a special way of adding webp to my HTML markup, my CSS, or even my JavaScript code. And guess what! There is no difference. So I removed all my jpg files and replaced them with webp files.

But that was not enough. My page paint was very expensive, so my Lighthouse audit score was not too much better. And load time in Firefox, Chrome, and Safari was still fairly slow. So what was I to do?

Then I thought of a React project that I had just completed, where I was retrieving images from the Robohash API and dynamically inserting the absolute path to these images retrieved from the API as the value of the img element’s src attribute. And sometimes, because of either the insertion approach or the API performance (probably a little of both), an image or two would render a the default browser placeholder image if the actual one did not upload immediately. Now this was some terrible UX, no?

I decided to add image lazy load functionality to my app. The difference was like night and day! No more placeholder images. Virtually no more load time! So I also added image lazy load functionality to my HTML/CSS/JS site.

I found a great article on regarding adding image lazy load using vanilla JavaScript, and it definitely improved the performance of my page tremendously. To read the article, please visit Lazy loading images with vanilla JavaScript on

For my purposes and edge case, I applied lazy load to all my images. I found that it sped up load time a bit more. I have to study the API, but it is basically the same as what I added to my React app. The only difference is that I did it with the help of a yarn package module.

Link to the page in question: letsbsocial on Github GH Pages

Link to the article I found regarding the WebP image file format on CSS Tricks: Using WebP Images

And if you don’t use Chrome and therefore don’t have the Lighthouse Chrome extension for auditing site performance, progressive web apps, best practices, accessibility, or seo, you can use the following site tool instead: PageSpeed Insights. It audits sites basically in the same way as Lighthouse. I just like Lighthouse better. But I did find that audits are not equal across browsers!