Lazy Load Products and Images in Magento 2

Posted on 23 March, 2019

Now a day, Images are a critical part of every websites and application. Either it is marketing banners, product images or logos, it is impossible to think a website without images.

Images are large in size making them the single biggest contributor to the page size. Because of large image size website takes too much time in loading.

To exit from this issue I am giving you the best solution and its lazy load image.

Lazy loading defers the loading of resources on the page as long as they are not needed. Instead of loading these resources as soon as the page loads, which is what normally happens, we defer a load of these resources to a later time when they are actually needed.

To apply to lazy load in Magento or any web page, set 'image-data-src' attribute in all image tag.

Let’s apply a lazy load in products in the catalog category page.

Go to <your_theme>/Magento/Catalog/templates/product/image_with_borders.phtml

1
2
3
4
5
6
7
8
9
10
11
<span class="product-image-container"
      style="width:<?= /* @escapeNotVerified */ $block->getWidth() ?>px;">
    <span class="product-image-wrapper"
          style="padding-bottom: <?= /* @escapeNotVerified */ ($block->getRatio() * 100) ?>%;">
        <img class="product-image-photo"
            <?= /* @escapeNotVerified */ $block->getCustomAttributes() ?>
            src="<?= /* @escapeNotVerified */ $block->getImageUrl() ?>"
            max-width="<?= /* @escapeNotVerified */ $block->getWidth() ?>"
            max-height="<?= /* @escapeNotVerified */ $block->getHeight() ?>"
            alt="<?= /* @escapeNotVerified */ $block->stripTags($block->getLabel(), null, true) ?>"/></span>
</span>

Replace it with

1
2
3
4
5
6
7
8
9
10
11
12
<span class="product-image-container"
      style="width:<?= /* @escapeNotVerified */ $block->getWidth() ?>px;">
    <span class="product-image-wrapper"
          style="padding-bottom: <?= /* @escapeNotVerified */ ($block->getRatio() * 100) ?>%;">
        <img class="product-image-photo"
            <?= /* @escapeNotVerified */ $block->getCustomAttributes() ?>
            src="<?= /* @escapeNotVerified */ $block->getViewFileUrl('images/loader-1.gif') ?>"
            image-data-src="<?= /* @escapeNotVerified */ $block->getImageUrl() ?>"
            max-width="<?= /* @escapeNotVerified */ $block->getWidth() ?>"
            max-height="<?= /* @escapeNotVerified */ $block->getHeight() ?>"
            alt="<?= /* @escapeNotVerified */ $block->stripTags($block->getLabel(), null, true) ?>"/></span>
</span>

Here I have added ‘image-data-src’ attribute and set image path in this attribute and set loading image in the src attribute. You can set src as a blank if you don’t need a loading image while image loading.

Except for product images you can also apply a lazy load in other images, in other image tags, add ‘image-data-src’ and set image path and blank src attributes.

Now add below script in your any global/ custom javascript file.

1
2
3
4
5
6
7
8
9
10
11
12
13
function lazyLoadImages() {
    var e = document.querySelectorAll("img[image-data-src]");
    [].forEach.call(e, function(e) {
        isElementInViewport(e) && (e.setAttribute("src", e.getAttribute("image-data-src")), e.removeAttribute("image-data-src"))
    }), 0 == e.length && (window.removeEventListener("DOMContentLoaded", lazyLoadImages), window.removeEventListener("load", lazyLoadImages), window.removeEventListener("resize", lazyLoadImages), window.removeEventListener("scroll", lazyLoadImages))
}
function isElementInViewport(e) {
    var t = e.getBoundingClientRect();
    return t.top >= 0 && t.left >= 0 && t.bottom <= (window.innerHeight || document.documentElement.clientHeight) && t.right <= (window.innerWidth || document.documentElement.clientWidth)
}
window.addEventListener("DOMContentLoaded", lazyLoadImages), window.addEventListener("load", lazyLoadImages), window.addEventListener("resize", lazyLoadImages), window.addEventListener("scroll", lazyLoadImages)

You can add below code if your image content/products are getting using Ajax then add below lines in your js file too.

1
2
3
4
5
/* for on ajax response images */
$(document).ajaxComplete(function() {
lazyLoadImages();
});

After applying the above solution and if you want to cross check then enable inspect element(F12) in your browser. Go to Network > select image filter then scroll your page you will get image requests for next visible images.


Nimita Gajera , eCommerce Project Manager

Magento Technical Notes

About Emipro

Being an emerging leader in IT market since 2011, Emipro Technologies Pvt. Ltd. has been providing a wide range of business solutions in Odoo & Magento. We are pleased to have a large pool of contented customers with our meticulous work in the domain of ERP & e-Commerce. Our customers are companies of all sizes ranging from startups to large enterprises who realize that they need a professional internet solution to generate revenue streams, establish proper communication channels, to achieve desired goals and streamline business operations. [....] Read More

Our writings seems informative ?

Subscribe for our Magento Technical Notes and get more amazing stuff directly to your inbox!

Post Your Review

X

Your Review has been posted

0 Comment(s)