Lazyload for Webflow Images

Hi @nxwebflow,

as for now, I did not succeed in using the noscript method suggested by @webdev to lazyload native Webflow srcset generated images. As an alternative solution, I am using a more complicated solution by hosting high res images on Cloudinary using lazysizes RIaS (Responsive Image as Service) extension to serve the proper image size and format(webP, etc…) for desktop and mobile. It’s really effective but need a bit more custom code here and there and is costly (cloudinary).

If someone have a noscript solution to play with (cloneable) for Webflow srcset image I’m happy to give it another try !

1 Like

Will you be updating this? lazyload 1.5.0 was released.

1 Like

@anthonysalamin - Were you trying to use the noscript plugin with data-sizes? I just double checked the noscript demo and it is working with WF responsive sizes.

@nxwebflow - Demo’s updated with version 5.1.0

1 Like

demo only shows the top of the page now


https://wf-images.webflow.io/lazy/lazy-sizes-no-script

1 Like

I checked the other page after changes, it worked. This one is broken. I restored the site back to what it was, and as soon as I have some free time, I will try to isolate the issue with 5.1.0.

1 Like

Hi @webdev,

Thanks for getting back to us !

I guess we are still struggeling to understand your webflow structure since there is no project to look at. Not sure what you mean by “The code we need to add is some basic HTML” since we can’t find that basic HTML reference on your demo page unless I’m mistaken.

From the lazysizes noscript plugin page on github, the structure looks like so:

<div class="lazyload" data-noscript="">
    <noscript>
        <p>any kind of content you want to be unveiled</p>
    </noscript>
</div>

From your demo screenshot, none of your .lazystart (<noscript>) or .lazyend (</noscript>) seem to be wrapped inside a parent div that would have a lazyload class and data-noscript="" attribute. Not entirely sure how and where you placed the lazyload and data-noscript attribute on your project ?

Here is my unsuccessfull attempt to reproduce your demo:
https://preview.webflow.com/preview/lazysizesnoscript?utm_source=lazysizesnoscript&preview=280533807610e651bfea7b6f01691946&mode=preview

My wf attempt to rebuild the lazysizes noscript extension structure:




2 Likes

@anthonysalamin - On your last slide, the class lazyloaded shows the script fired. If you look at the network panel in devtools, you will see that https://assets.website-files.com/5cf77f98eb100206ccf71836/5cf77f98eb10022730f71859_a_2x-p-500.jpeg was loaded by the script (see initiator). This indicates that the solution is working on your page.

1 Like

@webdev yes indeed, but it is fired on page load not when the element comes into view like on your demo. There is no change from “lazyload” to “lazyloaded”, just “lazyloaded” unfortunately. Your demo works, mine not :slight_smile:

1 Like

Here is temporary access to the RO of my project.
https://preview.webflow.com/preview/wf-images?utm_source=wf-images&preview=1ecc078ff81f294434d7ff1a6e4a8cea&mode=preview

@anthonysalamin → Here is the Head Code

<script src="https://cdn.jsdelivr.net/npm/lazysizes@4.1.8/lazysizes.min.js" integrity="sha256-fTBo7ekO22pjfhP1rQs1prKEo4Iu8eVPODvm0oOL5Xc=" crossorigin="anonymous"></script>
<!-- lazysizes noscript plugin load https://raw.githubusercontent.com/aFarkas/lazysizes/master/plugins/noscript/ls.noscript.min.js -->
<script>
  /*! lazysizes - v4.1.8 */
!function(a,b){var c=function(){b(a.lazySizes),a.removeEventListener("lazyunveilread",c,!0)};b=b.bind(null,a,a.document),"object"==typeof module&&module.exports?b(require("lazysizes")):a.lazySizes?c():a.addEventListener("lazyunveilread",c,!0)}(window,function(a,b,c){"use strict";var d={nodeName:""},e=!!a.HTMLPictureElement&&"sizes"in b.createElement("img"),f=a.lazySizes&&c.cfg||a.lazySizesConfig,g=function(a){var b,f,g,h,i,j=a.target.querySelectorAll("img, iframe");for(b=0;b<j.length;b++)f=j[b].getAttribute("srcset")||"picture"==(j[b].parentNode||d).nodeName.toLowerCase(),!e&&f&&c.uP(j[b]),j[b].complete||!f&&!j[b].src||(a.detail.firesLoad=!0,h&&i||(i=0,h=function(b){i--,b&&!(i<1)||g||(g=!0,a.detail.firesLoad=!1,c.fire(a.target,"_lazyloaded",{},!1,!0)),b&&b.target&&(b.target.removeEventListener("load",h),b.target.removeEventListener("error",h))},setTimeout(h,3500)),i++,j[b].addEventListener("load",h),j[b].addEventListener("error",h))};f||(f={},a.lazySizesConfig=f),f.getNoscriptContent=function(a){return a.textContent||a.innerText},a.addEventListener("lazybeforeunveil",function(a){if(a.detail.instance==c&&!a.defaultPrevented&&null!=a.target.getAttribute("data-noscript")){var b=a.target.querySelector('noscript, script[type*="html"]')||{},d=f.getNoscriptContent(b);d&&(a.target.innerHTML=d,g(a))}})});
</script>
3 Likes

What issue with 5.1.0? Seems to be working fine on the site I made https://fooxea.com

1 Like

EDIT:

I apologize. It works perfectly… I had the impression it was loading on page load because the intersection observer of lazysizes probably has a rootMargin higher than 0… I have set up the placeholder to be 500vh instead of 100vh and the image loads only after having scrolled quite a while before gettin into view.

By the way @nxwebflow, I tried with the lazysies v5.1.0 plugin as well, everything works as expected.

Thanks again @webdev !

https://www.loom.com/share/3a39ace7c5dc4f7c8c8d7581229cb33b

1 Like

Is it possible to adjust when the image gets lazyloaded?

1 Like

Options are visible at:

2 Likes

Hi guys! Very rookie question… Do you need to upload a low-res version of every image you want lazy-loaded or does the plugin create one for you (maybe blurred like Medium.com)?

1 Like

Hi @Edoardo_Rainoldi,

With the technique @webdev suggested, you don’t need to upload low-res version of every image since the lazysizes extension will lazy load the native webflow srcset image.

If you want to use the LQIP technique (low quality image placeholder) with nice blury effect, I suggest you use Cloudinary which offers alot of amazing options. You’d host one high res master image on their platform, they then do the rest for you: deliver the right image size, resolution, dpr, format etc…

1 Like

Ah it makes sense! So expensive though.

Thank you for the help @anthonysalamin :slight_smile:

1 Like

Hey @anthonysalamin, I’ve been looking around trying to learn more about CDNs and stuff. I found a cheap one called imagekit.io the only issue is that to make it work you would need to replace the img-src links for every image from uploads-ssl.webflow.com/path/to/my-image.jpg to https://ik.imagekit.io/rooki/path/to/my-image.jpg.

Is there any automated to do that since Webflow doesn’t let you change the src attribute? Or does Cloudinary do it for you? I feel like the only way to do it now is implementing images with custom HTML but I don’t think it would work in my case because I’m using the CMS.

1 Like

Hi @Edoardo_Rainoldi,

I don’t know imagekit.io, if I were you I would use the noscript method suggested by webdev to wrap your cms images in order to lazyload them. If you upload the image via Webflow CMS, there is, to my knowledge, unfortunately no way to change the path to your images as you suggested.

1 Like

Hi @webdev and @anthonysalamin, just tried to implement your lazyload method but it doesn’t work. The whole wrapped element doesn’t load at all.

Here’s my head code (I also load the unveilhooks plugin for background images):

<script src="https://cdn.jsdelivr.net/npm/lazysizes@5.1.0/lazysizes.min.js" integrity="sha256-fTBo7ekO22pjfhP1rQs1prKEo4Iu8eVPODvm0oOL5Xc=" crossorigin="anonymous"></script>

Here’s my RO link: https://preview.webflow.com/preview/rooki-design?utm_source=rooki-design&preview=245da9daed8d9b3944285b3e9b73d0ba&mode=preview

1 Like

@Edoardo_Rainoldi, you forgot to load the noscript extension from lazysizes.
Here is the code you’re looking for:

<!-- lazysizes v5.1.0 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.0/lazysizes.min.js"></script>
<script>
/**
 * lazysizes noscript extension v5.1.0
 * https://raw.githubusercontent.com/aFarkas/lazysizes/master/plugins/noscript/ls.noscript.min.js
 */
!function(a,b){var c=function(){b(a.lazySizes),a.removeEventListener("lazyunveilread",c,!0)};b=b.bind(null,a,a.document),"object"==typeof module&&module.exports?b(require("lazysizes")):a.lazySizes?c():a.addEventListener("lazyunveilread",c,!0)}(window,function(a,b,c){"use strict";var d={nodeName:""},e=!!a.HTMLPictureElement&&"sizes"in b.createElement("img"),f=a.lazySizes&&c.cfg,g=function(a){var b,f,g,h,i,j=a.target.querySelectorAll("img, iframe");for(b=0;b<j.length;b++)f=j[b].getAttribute("srcset")||"picture"==(j[b].parentNode||d).nodeName.toLowerCase(),!e&&f&&c.uP(j[b]),j[b].complete||!f&&!j[b].src||(a.detail.firesLoad=!0,h&&i||(i=0,h=function(b){i--,b&&!(i<1)||g||(g=!0,a.detail.firesLoad=!1,c.fire(a.target,"_lazyloaded",{},!1,!0)),b&&b.target&&(b.target.removeEventListener("load",h),b.target.removeEventListener("error",h))},setTimeout(h,3500)),i++,j[b].addEventListener("load",h),j[b].addEventListener("error",h))};f.getNoscriptContent=function(a){return a.textContent||a.innerText},a.addEventListener("lazybeforeunveil",function(a){if(a.detail.instance==c&&!a.defaultPrevented&&null!=a.target.getAttribute("data-noscript")){var b=a.target.querySelector('noscript, script[type*="html"]')||{},d=f.getNoscriptContent(b);d&&(a.target.innerHTML=d,g(a))}})});
</script> 

Hope that helps.

1 Like