Lazyload for Webflow Images

Can’t wait !

Thank you for taking the time to share the knowledge !
Yes, it would be awesome if Webflow could implement a native lazyloading method for all type of images, responsive or not. Surely such feature is no easy task from an infrastructure point of view also, but well dreaming is good.

2 Likes

@cheechee provided a solution above that makes it trivial to lazy load with or without webflow responsive image generation, CMS images, and slides. Take a look. I tested it and it works.

Noscript Demo created > Lazy Sizes No Script with Webflow

8 Likes

Hi @cheechee,

Sounds indeed really interesting ! what a lovely hack to wrap / squeeze the image in between two webflow embeds :slight_smile:

One question though, how does that work if lazysizes uses the data-srcset attibute and not the srcset attribute that webflow actually uses when the page is created ?

Here is snipet from the lazysizes documentation:
responsive image with srcset and sizes attribute
Simply use data-srcset and you can support responsive images.

<img
	alt=""
	sizes="(min-width: 1000px) 930px, 90vw"
	data-srcset="small.jpg 500w,
		medium.jpg 640w,
		big.jpg 1024w"
	data-src="medium.jpg"
	class="lazyload" />

Thank you for your help !
A.

1 Like

I added an image to the Noscript demo page that webflow created responsive versions and tag. Class assed to image. Working. It is being loaded by the plugin, which you can confirm in the network panel of chrome dev tools (see the initiator).

2 Likes

Thank you @webdev ! Will dig into those upcoming day.

I spent some time digging into the Cloudinary documentation again and found an interesting article describing a way to serve responsive images via automatic url transformation through javascript SDK from Cloudinary.

I came up with a codepen test:
https://codepen.io/anthonysalamin/pen/VNJZxJ?editors=1010

Would you say it is the way to go for responsive imagery ? Does this method replace the srcset method effectively ? Knowing I’d like to then lazyload those responsive images with the Lazy Load lazyload powerfull lazyload script.

Here is my old srcset markup alternative (working but tedious to update all srcset attributes…)

Thanks for your precious insights !
A.

1 Like

I am doing this right now off on site hosted on one of my servers. I tested in WF and it works fine. When you have a src file defined, you can obviously see it in the designer. I am using LOW quality for the src and then letting the API generate the responsive images. I did test auto generation on type and webp images are served when supported as well.

You can. I am doing this for a resort site now.

I am working on a demo for the complete gamut and will have it up soon.

2 Likes

Really looking forward to it !

Quick question, is it possible / does it make sense to set the url transformation in the javascript directely to preserve a clean URL in the HTML ? I will have quite some images in my feed, if I decide to set the quality to let’s say 70, I’ll have to manually tweak all my URLs - if I have it set up in the javascript snipet, I’d just change one line. I looked into the documentation but find it relatively obscure to understand / implement.

Here is my codepen again:
https://codepen.io/anthonysalamin/pen/VNJZxJ?editors=1010

1 Like

I did try to update the url via Cloudinary javascript SDK but it does not work anymore. I must be missing something.

EDIT:

Almost there ! :sunglasses: (still not working)
https://codepen.io/anthonysalamin/pen/vMoOmv?editors=1010

I know dynamically generate data-src images based on the low res src image. The javascript then applies the cloudinary transformation dynamically aswell. The whole thing is being successfully lazy loaded…

… but it seems the very same image is being served, regardelss of the window’s width. I tried to rescale my browser’s window from big to very small, it seems the image is the same size after download → same image which does not change (like it is supposed to be with Cloudinary cl.responsive(); function.

I’m still missing something, can’t figure out what :slight_smile:

Here the version with pure cloudinary working responsive image but without lazy load:

1 Like

Okay,

I think I got it right now, used Lazysizes aswell. I got inspired by someone else on codepen lazyloading cloudinary images but had quite different structure… I rewrote the javascript to fit my webflow workflow, seems to work. Let me know what you think !

Documentation:
http://afarkas.github.io/lazysizes/rias/

Codepen:
https://codepen.io/anthonysalamin/pen/OYJgWJ?editors=1010

Live website:
https://lazycloudinary.webflow.io/

Webflow read-only:
https://preview.webflow.com/preview/lazycloudinary?utm_source=lazycloudinary&preview=304d59c4f8a57c38ac08a2303e0a45e8

Hope this can help someone too !

2 Likes

Hi @webdev,

I gave it a try today ! :slight_smile:

I must be however missing something since the google dev tool network shows me no progressive image loading, everything is loaded on page load, strangely.

Here is a video recording:

Here is my read-only link:
https://preview.webflow.com/preview/sticky-section-f38b32?utm_source=sticky-section-f38b32&preview=836a8217234897977eb5df2ab6f40c88

1 Like

Should I only lazy load sections that are under the initial page that loads?

heres my read only link: https://preview.webflow.com/preview/fooxea?utm_source=fooxea&preview=642701297951d08087e9cba40bd86c2b&mode=preview

1 Like

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