Jump to content
Search Community

Pattern(s) for synchronizing ScrollTrigger and Lenis in React/Next

granularclouds test
Moderator Tag

Recommended Posts

Hello! I started working on a project in which I'm using both Lenis (ReactLenis) and Scrolltrigger on a different, slower machine and am noticing very poor framerates on scroll (whereas on the beefier machine, the scroll animations were fluid, fast). Commenting out ReactLenis restores performance. 

 

My question is: how to make scrolltrigger and lenis play nice in React/Next. This is not really a "help me achieve outcome X" in this sandbox/codepen question, moreso a higher-level, best practices "what is the right/recommended way to do Y" question 

 

For example, in the React Lenis docs, they suggest synchronizing Lenis and GSAP like this:

 

function Component() {
  const lenisRef = useRef()
  
  useEffect(() => {
    function update(time) {
      lenisRef.current?.lenis?.raf(time * 1000)
    }
  
    gsap.ticker.add(update)
  
    return () => {
      gsap.ticker.remove(update)
    }
  })
  
  return (
    <ReactLenis ref={lenisRef} autoRaf={false}>
      { /* content */ }
    </ReactLenis>
  )
}

 

While in their Next.js starter, synchronization appears to be spread across two files: this more scrollTrigger specific one; and this more generic GSAP one (in the combined setup featured these two files, there is no wrapping ReactLenis element, also).

 

So, again. Just wondering if any GSAP people have a recommended/best practice approach for doing this. As I keep seeing different patterns. Totally fine if this question is ineligible because this isn't a Lenis Q&A board, but I feel like these two tools are used together enough that someone on here might have some clarity.

 

Thanks!

 

Link to comment
Share on other sites

Hi,

 

I never used Lenis with GSAP and React so I couldn't really tell you about it. This does look odd to me TBH:

useEffect(() => {
  function update(time) {
    lenisRef.current?.lenis?.raf(time * 1000)
  }

  gsap.ticker.add(update)

  return () => {
    gsap.ticker.remove(update)
  }
})

That useEffect hook doesn't have any dependencies, so every time that component re-renders all that is called again, I would use an empty dependencies array, but they must have a reason for suggesting that.

 

Also Lenis is not a GSAP product so we can't really offer support for it, we have our own smooth scrolling solution in ScrollSmoother:

https://gsap.com/docs/v3/Plugins/ScrollSmoother/

 

Finally performance is a really deep topic and most likely this is tied to perhaps the Lenis react wrapper eating quite some resources and creating this rather than a GSAP specific problem and I don't recall other threads in the forums on this particular subject.

 

Sorry I can't be of more assistance, hopefully other users with more experience with lenis and react can chime in.

 

Happy Tweening!

Link to comment
Share on other sites

Thank you - I know about ScrollSmoother but between not wishing to tie a feature for a site to a subscription package and also not wishing to work around the position: fixed limitation, for this project in particular I would go with Lenis.

 

I tried a bunch of stuff and the performance is just not ideal, so I think I'll stick with ScrollTrigger and scrub and ditch the smoothing for non-animation things. 

 

Thanks!

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...