Skip to main content
All CollectionsSettings and Troubleshooting FAQ
Can I lazy load the images in my recommendation slot?
Can I lazy load the images in my recommendation slot?

Do you want to get the graphic content of your Nosto's slot loaded only when it literally hits the screen? Here we show you how it is done.

Jacopo Carassai avatar
Written by Jacopo Carassai
Updated over 6 years ago

It is renowned: the online retail ecosystem can be thought as a jungle, and only the fastest creatures survive.
According to a self conducted test, Amazon proved that - if the website would be slowed down by just one second - they would loose $1.6 billion (yes, BILLION!) a year.
Also, another research from Kissmetric has pulled the following stats:

  • 47% of your visitors expect your site to load in less than 2 seconds;

  • 40% will abandon it entirely if it takes longer than 3 seconds;

  • 85% are expecting the mobile site to load faster than the desktop version.

I know - and you do, too - that Nosto has a microscopic impact on the overall loading time of your website and most of it comes from the caching of images within the recommendation slot, as they get downloaded when the DOM element is created.
Take this example: if you have placed a Nosto's recommendation slot at the very bottom of your page, why should its images be downloaded in the cache also when the user hasn't scrolled to there yet?

This can be optimized; in fact, you can load the images only when they enter in the viewport (aka, for muggles, the visible area of the screen).
For you I have written this little (and minified!) script in Vanilla JS, which looks like:

<script type="text/javascript">
var lazy=[],nostoW=_targetWindow.window,nostoD=_targetWindow.document;function recordListener(t,e){nostoW.addEventListener?nostoW.addEventListener(t,e):nostoW.attachEvent("on"+t,e)}function lazyLoad(){for(var t=0;t<lazy.length;t++)hasHitViewport(lazy[t])&&lazy[t].getAttribute("data-src")&&(lazy[t].src=lazy[t].getAttribute("data-src"),lazy[t].removeAttribute("data-src"));resetLazy()}function resetLazy(){lazy=Array.prototype.filter.call(lazy,function(t){return t.getAttribute("data-src")})}function hasHitViewport(t){var e=t.getBoundingClientRect();return e.bottom>=0&&e.right>=0&&e.top<=(nostoW.innerHeight||nostoD.documentElement.clientHeight)&&e.left<=(nostoW.innerWidth||nostoD.documentElement.clientWidth)}recordListener("load",lazyLoad),recordListener("scroll",lazyLoad),recordListener("resize",lazyLoad),lazy=nostoD.getElementsByClassName("lazy-nosto"),console.log("Found "+lazy.length+" lazy images"),_targetWindow.nostojs(function(t){t.listen("postrender",function(t){lazyLoad()})});
</script>

If you are not a code savvy (but also if you are) I spare you the technicalities of this script, and just copy it all and paste it at the very bottom of your template.

As a next step you have to find where, in the template, your images' element are placed; once spotted, add to the element the class lazy-nosto and change the attribute from src to data-src, so that if you already have something like this:

<img src="$!product.thumb(8)" class="myClass">

in the end will have to look like this: 

<img data-src="$!product.thumb(8)" class="myClass lazy-nosto">

If you are worried your users are surfing on old browsers, or that they have disabled the execution of scripts from websites, add a <noscript> clause just after the <img> element, something like this:

<img data-src="$!product.thumb(8)" class="myClass lazy-nosto">
<noscript>
    <img src="$!product.thumb(8)" class="myClass">
</noscript>


If you have followed this guide step by step, you will have the images of your Nosto's recommendation slot loaded only when they enter the viewport of the page.
N.B. with the modern high-speed Internet connections (also, for example, 4G on mobile) images get downloaded so fast that, if you are a human, you will probably not be able to see with your eyes them being downloaded.

Did this answer your question?