Table of contents
- What is Image Lazy Loading?
- Why go for lazy loading images at all?
- Which Images can be Lazy Loaded?
- Lazy Loading Techniques for images
- The general concept of lazy loading images in <img> tag
- Trigger image load using Javascript events
- Using Intersection Observer API to trigger image loads
- Better user experience with lazy loading images
- 1. Using the right image placeholders
- 2. Adding some buffer time for image load
- 3. Avoiding content shifting with lazy loading
- 4. Do not lazy load all the images
- Javascript dependency of Lazy Loading
- Popular Javascript libraries for lazy loading on your websit
- Conclusion
What is Image Lazy Loading?
Lazy Loading Images is a set of techniques in web and application development that defer the loading of images on a page to a later point in time – when those images are actually needed, instead of loading them up front. These techniques help in improving performance, better utilization of the device’s resources, and reducing associated costs.
The word “lazy” in the English language is often attributed to the act of avoiding work as long as possible.
Similarly, lazy loading defers the loading of resources on the page till they are actually needed. Instead of loading these resources as soon as the page loads, which is what normally happens, the loading of these resources is put off till the moment the user actually needs to view them.
Why go for lazy loading images at all?
Lazy Loading defers the loading of an image that is not needed on the page immediately. An image, not visible to the user when the page loads, is loaded later when the user scrolls and the image actually becomes visible. If the user never scrolls, an image that is not visible to the user never gets loaded.
It carries two main advantages.
1. Performance Improvement
This is the most important one for you as a website administrator – better performance and load time.
With lazy loading, you are reducing the number of images that need to be loaded on the page initially. Lesser resource requests mean lesser bytes to download and lesser competition for the limited network bandwidth available to the user. This ensures that the device is able to download and process the remaining resources much faster. Hence, the page becomes usable much sooner as compared to one without lazy loading.
2. Cost reduction
The second benefit for you is in terms of delivery costs. Image delivery, or delivery of any other asset, is usually charged on the basis of the number of bytes transferred.
As mentioned earlier, with lazy loading, if the image is not visible, it never gets loaded. Thus, you reduce the total bytes delivered on the page., especially for users that bounce off the page or interact with only the top portion of the page. This reduction in bytes transferred from your delivery network reduces delivery costs. This will become more apparent as we explore lazy loading further.
Which Images can be Lazy Loaded?
The basic idea of lazy loading is simple – defer loading anything that is not needed right now. For images it usually translates to any image that is not visible to the user up front can be lazy loaded.
As the user scrolls down the page, the image placeholders start coming into viewport (visible part of the webpage). We trigger the load for these images when they become visible.
Lazy Loading Techniques for images Images on a webpage can be loaded in two ways – using the <img> tag, or using the CSS `background` property. Let’s first look at the more common of the two, the <img> tag, and then move on to CSS background images
The general concept of lazy loading images in <img> tag
Lazy loading images can be broken down into two steps:
Step one is to prevent the image load up front. For images loaded using the <img> tag, the browser uses the src attribute of the tag to trigger the image load. Irrespective of whether it is the 1st or the 1000th image in your HTML and well off-screen, if the browser gets the src attribute, it would trigger the image load.
Thus, to lazyload such images, put the image URL in an attribute other than src. Let’s say we specify the image URL in the data-src attribute of the image tag. Now that src is empty, the browser doesn’t trigger the image load
<img data-src=”https://ik.imagekit.io/demo/default-image.jpg” />
Now that we’ve stopped the upfront load, we need to tell the browser when to load the image.
For this, we check that as soon as the image (i.e., its placeholder) enters the viewport, we trigger the load.
To check when an image enters the viewport, there are two ways:
Trigger image load using Javascript events
In this technique, we use event listeners on the scroll, resize, and orientationChange events in the browser. The scroll event is an obvious one to check when the user scrolls the page. The resize and orientationChange events are equally important for lazy loading. The resize event occurs when the size of the browser window changes. The orientationChange event gets triggered when the device is rotated from landscape to portrait mode, or vice versa. In such cases, the number of images that become visible on the screen will change. Therefore, we’ll need to trigger a load for these images.
When either of these events occur, we find all the images on the page that are to be lazy loaded and haven’t been loaded yet. From these images, we check which ones are now in the viewport. This is done using the image’s top offset, the current document scroll top, and window height. If it has entered the viewport, we pick the URL from data-src attribute and put it in the src attribute. This triggers the image load. We also remove the class lazy that identifies the images to be lazily loaded for events that trigger later. Once all the images are loaded, we remove the event listeners.
When we scroll, the scroll event triggers multiple times rapidly. Thus, for performance, we add a small timeout that throttles the lazy loading function execution.
Here is a working example of this approach.
If you notice, the first 3 images in the example are loaded up front. The URL is present directly in the src attribute instead of the data-src attribute. This is essential for a good user experience. Since these images are at the top of the page, they should be made visible as soon as possible. We must not wait for an event or JS execution to load them.
Now that we’ve stopped the upfront load, we need to tell the browser when to load the image.
For this, we check that as soon as the image (i.e., its placeholder) enters the viewport, we trigger the load.
To check when an image enters the viewport, there are two ways:
Trigger image load using Javascript events
In this technique, we use event listeners on the scroll, resize, and orientationChange events in the browser. The scroll event is an obvious one to check when the user scrolls the page. The resize and orientationChange events are equally important for lazy loading. The resize event occurs when the size of the browser window changes. The orientationChange event gets triggered when the device is rotated from landscape to portrait mode, or vice versa. In such cases, the number of images that become visible on the screen will change. Therefore, we’ll need to trigger a load for these images.
When either of these events occur, we find all the images on the page that are to be lazy loaded and haven’t been loaded yet. From these images, we check which ones are now in the viewport. This is done using the image’s top offset, the current document scroll top, and window height. If it has entered the viewport, we pick the URL from data-src attribute and put it in the src attribute. This triggers the image load. We also remove the class lazy that identifies the images to be lazily loaded for events that trigger later. Once all the images are loaded, we remove the event listeners.
When we scroll, the scroll event triggers multiple times rapidly. Thus, for performance, we add a small timeout that throttles the lazy loading function execution.
Using Intersection Observer API to trigger image loads
Intersection Observer API is a relatively new API in browsers. It makes it really simple to detect when an element enters the viewport, and take an action when it does. In the previous method, we had to bind events, keep performance in mind, and implement a way to calculate if the element was in the viewport or not. The Intersection Observer API makes this really simple, helps avoid the math, and delivers great performance.
Better user experience with lazy loading images
Lazy loading presents a great performance benefit. For an e-commerce company that loads hundreds of product images on a page, lazy loading can provide a significant improvement in initial page load time while decreasing the bandwidth consumption.
Popular Javascript libraries for lazy loading on your website
Since browser environments and implementation details can vary across browsers and devices, it is best to use a tried and tested library for lazy loading.
Here is a list of popular libraries and platform specific plugins that will allow you to implement lazy loading with minimal effort
yall.js (Yet Another Lazy Loader)
- Uses Intersection Observer and falls back to event-based lazy loading.
- Supports all major HTML element types but not background-images.
- Works on IE11+ as well.
lazysizes
- Very popular and extensive functionality.
- Supports responsive images srcset and sizes attribute as well.
- High performance even without an Intersection Observer.
jQuery Lazy
- A simple, jquery based lazy loading library.
- A Shopify extension for lazy loading images.
- It is paid though.
- Image lazy loading plugin for WordPress.
Conclusion
We have covered almost everything related to lazy loading images in this guide. Lazy loading, if implemented correctly, will significantly improve the loading performance of your web pages, reduce page size and delivery costs by cutting down on unnecessary resources loaded up front, while keeping the necessary content intact on the page. With faster loading pages comes a great user experience, something your visitors would love.