Jump to content
Search Community

loading="lazy" and ScrollTrigger.refresh()

VoinG test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hello,
i can't let it go) I often see problems with ScrollTrigger and img loading="lazy", i have some problems too )

 

loading="lazy"

is a nice thing, WordPress has it active by default. I don't want to do without it voluntarily.


The recommended solution is to use

ScrollTrigger.refresh()

I have to admit, I don't quite understand how or when exactly to use it. I think, whenever browser loads the new "lazy" image? I wrote a little script, is that correct from your point of view?

 



This seems to work fine even with multiple images getting in the viewport at the same time. 
But in my "yellow example" which some have already seen, it works (also in Firefox!!!) but rattles and jumps, especially when more images get into viewport at the same time.. 

 

https://cdpn.io/pen/debug/gOBvaga?authentication_hash=LQMExZYbPemk (please open it)

What am I doing wrong? What can I do better? Thank you very much!

See the Pen LYgewVp by design4u-koeln (@design4u-koeln) on CodePen

Link to comment
Share on other sites

  • Solution

Here's a helper function I whipped together for handling lazy loading stuff: 

function handleLazyLoad(config={}) {
  let lazyImages = gsap.utils.toArray("img[loading='lazy']"),
      timeout = gsap.delayedCall(config.timeout || 1, ScrollTrigger.refresh).pause(),
      lazyMode = config.lazy !== false,
      imgLoaded = lazyImages.length,
      onImgLoad = () => lazyMode ? timeout.restart(true) : --imgLoaded || ScrollTrigger.refresh();
  lazyImages.forEach((img, i) => {
    lazyMode || (img.loading = "eager");
    img.naturalWidth ? onImgLoad() : img.addEventListener("load", onImgLoad);
  });
}

// usage: you can optionally set lazy to false to change all images to load="eager". timeout is how many seconds it throttles the loading events that call ScrollTrigger.refresh()
handleLazyLoad({ lazy: false, timeout: 1 });

Basically you just call the method and it'll manage calling ScrollTrigger.refresh() for you at the appropriate time. You can optionally pass in a config object to set everything to NOT be lazy (lazy: false) and you can also control how long it waits after each image loads to call ScrollTrigger.refresh(). For example, if 5 images load in quick succession, you shouldn't need to call ScrollTrigger.refresh() 5 times. By default, it waits 1 second to see if another one loads. If another one does, it starts the timer over again...so when 1 second elapses when no more images have loaded, it'll fire ScrollTrigger.refresh(). That improves performance. 

 

But again, I recommend not doing lazy loading. :)

 

I definitely would not use that function you wrote - it's extremely inefficient. Literally on every single scroll event (those fire a LOT during scroll), it is doing CPU-intensive calculations to map all the position of every image. The function I provided above is many, many times more efficient. 

  • Like 4
Link to comment
Share on other sites

@GreenSock
Thank you very much! This is very nice code! img.addEventListener("load",()) is sure the correct event and not $(window).scroll(function (){}). The use of timeout definitely makes sense! It works very well for my purposes (without or with WP).

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...