Page Load Optimization using image lazy loading for Liferay page

Image lazy loading

Introduction

One of the core and key requirement is page and site performance. It depends on various factors. One factor is number of images loaded on the page and its loading time. The images resides either on server or are cached in Content Delivery Network (CDN).

When the page is getting loaded, browser makes requests to page resources like images. The images get downloaded on browser which significantly contribute to the overall page load time. This time also depends on -

  • Type of image - Some of the image formats like PNG are more in size and take more time but images like JPG /WEBP are lighter and take comparatively less time. So, its recommended to use WEBP images wherever possible.
  • Image resolution- Higher the resolution of image, more time is taken to load it on page.
  • Number of images – Number of images loaded during the page load.
  • Synchronous loading of HTML, CSS, JavaScript and images – Most times all resources gets loaded in synchronous way leading to high load time.

Most of the time, we can’t control the number of images getting loaded on the page as it might be required on the page as per business requirement. Thus we need to find a way where the images are only been fetched by browser when they appear in the view section of the page.

For Liferay, Liferay has its own product CSS, JavaScript resources getting loaded on page.

Below sample script will help to achieve the above said lazy loading behavior of the images –

 

var lazyloadImages;   

 

if ("IntersectionObserver" in window) {

 

  lazyloadImages = document.querySelectorAll(".lazy");

 

  var imageObserver = new IntersectionObserver(function(entries, observer) {

 

    entries.forEach(function(entry) {

 

      if (entry.isIntersecting) {

 

        var image = entry.target;

 

               if(image.src==undefined || image.src==null || image.src==""){

 

                       image.src = image.dataset.src;

 

                       image.classList.remove("lazy");

 

               }

 

        imageObserver.unobserve(image);

 

      }

 

    });

 

  });

 

 

 

  lazyloadImages.forEach(function(image) {

 

    imageObserver.observe(image);

 

  });

 

} else { 

 

  var lazyloadThrottleTimeout;

 

  lazyloadImages = document.querySelectorAll(".lazy");

 

 

 

  function lazyload () {

 

    if(lazyloadThrottleTimeout) {

 

      clearTimeout(lazyloadThrottleTimeout);

 

    }   

 

 

 

    lazyloadThrottleTimeout = setTimeout(function() {

 

      var scrollTop = window.pageYOffset;

 

      lazyloadImages.forEach(function(img) {

 

          if(img.offsetTop < (window.innerHeight + scrollTop)) {

 

                 if(img.src==undefined || img.src==null || img.src==""){

 

                         img.src = img.dataset.src;

 

                         img.classList.remove('lazy');

 

                 }

 

          }

 

      });

 

      if(lazyloadImages.length == 0) {

 

        document.removeEventListener("scroll", lazyload);

 

        window.removeEventListener("resize", lazyload);

 

        window.removeEventListener("orientationChange", lazyload);

 

      }

 

    }, 20);

 

  }

 

 

 

  document.addEventListener("scroll", lazyload);

 

  window.addEventListener("resize", lazyload);

 

  window.addEventListener("orientationChange", lazyload);

 

}

 

Inter Section Observer object checks if the HTML elements are currently under the view section where user will see the HTML content of that part and based on that the Image Observer will check and load the image by assigning the path in source attribute. Hence the actual image on the page will only be loaded when requested. Some of the images which are displayed on panel which is not shown by default or the bottom section images which are currently not under viewpoint are not loaded on page load. But rather they are loaded when user scroll down to the bottom section or opens the panel by hover or click on some link/button.

 

Advantage

  1. This helps to improve page load performance as the image is only loaded when requested.
  2. This also reduces overhead on CDN or web browser as the number of http requests gets reduced.
  3. There is a limitation on number of concurrent requests a browser can make, for the situations where the number of CSS, JavaScript and especially number of images is high, this will help in overall reduction of page size and overhead on the browser.