Jump to content
Search Community

Gsap + ScrollTrigger with SvelteKit - performance issue

zofia test
Moderator Tag

Recommended Posts

Hello everyone,

 

I am building a simple website in SvelteKit and Gsap + scrollTrigger. The structure is something like this: Startpage /  About / Services / Contact

 

Throughout the site, I use simple animations on SVG, texts and other elements. Everything seems fine, but as I move back and forth between pages, I noticed that the webpage was really slowing down. The more I navigate, the slower this becomes and eventually the website/browser starts to hang or crash. After refreshing the browser everything is fine again… (until I start navigating between pages again).

 

I use gsap like this on all route pages:

 

 

<script>

// GSAP
import { gsap }                 from 'gsap';
import { ScrollTrigger }        from 'gsap/dist/ScrollTrigger.js';
import { onMount, onDestroy }   from 'svelte';
   

const init = () => {


// Title + Circles
let tlHero = gsap.timeline({
    defaults: {duration: 1, ease: "power2"}, 
    scrollTrigger: {
        trigger: ".index h1",
        toggleActions: "restart none restart none", 
    }
});

tlHero
    .from(".index h1", {x: 40, delay:0.3)
    .from(".hero-c2", {duration: 0.8, scale:0.1, transformOrigin:"50% 100%"})
    .from(".hero-c3", {y:-31, delay:0.3}) 
    .from(".hero-c1", {y:32}, "-=1") 

 // Titles - .lists sections
 const sections = gsap.utils.toArray('.lists section');
 sections.forEach((section) => {
    gsap.from(section, {
    x:100,
    skewX:5,
    duration: 2,
    stagger:5,
    ease: 'power4',
    opacity:0,
    scrollTrigger: {
        trigger: section,
        toggleActions: 'restart none none reverse',
        start: 'top 80%',
      }
    });
  });

  // […] and here several other animations…

};


onMount(() => {
    gsap.registerPlugin(ScrollTrigger);
    init();
});

</script>

 

What am I doing wrong? I feel it’s a memory issue (?) and I should kill my scroll triggers on page exit and reinitialize them when I’m back, but I don’t know how and where to do it in my svelte small project. Or maybe it is just something else... I am still at the beginning of my programming journey, so please forgive me if the solution is too obvious for you... :)

 

I tried to use:

tlHero.scrollTrigger.kill();

 

… but when I leave the page (eg from /about to /contact) and come back, the trigger doesn’t work.

 

I would appreciate any help 😊🙏

I’m using SvelteKit and I’m not sure if I could provide a demo on Codepen... I hope it won't be needed, please let me know.

 

Best

Zofia

Link to comment
Share on other sites

Hi there Zofia,

This sounds to me like you're creating additional timelines every time you change page - like you said - You'll need to kill the ScrollTriggers on page transition and re-initialize them again on entering the new page.

This is a good snippet that will kill all of them

 

let triggers = ScrollTrigger.getAll();
 triggers.forEach( trigger => {			
  trigger.kill();
});
 

I'm afraid I'm not familiar with sveltekit though - You'll have to find the right lifecyle method to kill the 'old' ScrollTriggers and re-initialize the 'new'

 

It may be worth asking the sveltekit crew about that if no one here can help you?

 

I hope this helps a little, sorry I can't give you a solution.

  • Like 1
Link to comment
Share on other sites

thank you guys!

 

@Cassie - I managed to kill the ScrollTriggers but I can't bring them back to life :) I will definitely ask the Svelte team if I fail to figure it out ;) 

@OSUblake- yes, I tried onDestroy but without success. I'll create a demo and be back... and who knows, maybe a solution will come along the way :)

Link to comment
Share on other sites

 

6 minutes ago, zofia said:

I managed to kill the ScrollTriggers but I can't bring them back to life :) I will definitely ask the Svelte team if I fail to figure it out ;) 

 

Do the onMount and onDestroy fire when you leave and come back? You should see the before and after console.log values change. 

 

onMount(() => {
  console.log("ScrollTriggers before mount", ScrollTrigger.getAll().length);
  init();
  console.log("ScrollTriggers after mount", ScrollTrigger.getAll().length);
});

onDestroy(() => {
  console.log("ScrollTriggers before destroy", ScrollTrigger.getAll().length);
  ScrollTrigger.getAll().forEach(trigger => trigger.kill());
  console.log("ScrollTriggers after destroy", ScrollTrigger.getAll().length);  
});

 

  • Like 1
Link to comment
Share on other sites

That looks weird, like onMount doesn't get called again. I would expect it to log out something like this.

ScrollTriggers before mount
ScrollTriggers after mount
ScrollTriggers before destroy
ScrollTriggers after destroy
ScrollTriggers before mount
ScrollTriggers after mount
ScrollTriggers before destroy
ScrollTriggers after destroy

 

So it seems you need to find a way to get onMount, or some way to re-initialize stuff when you navigate to to a new page. I'm not sure how to do that though. It seems that is a problem with svelte.

https://github.com/sveltejs/kit/issues/552

 

  • Like 2
Link to comment
Share on other sites

Oh no, I've created so many GSAP animations and now something like this.. 😮 So as I understand it, I have to look for help on the Svelte forums. Or maybe @Dipscom you could help here, please? 🙏🙏 I see you have quite a bit experience with Svelte. 🙂 

 

@OSUblake thank you very much for your help. Hopefully, I'm a step closer to solving my problem

  • Like 2
Link to comment
Share on other sites

@OSUblake @Cassie

I just found out that my problem was caused by page transitions. When I throw them away, everything works as it should with GSAP ScrollTrigger

Here is the code that caused the problem:

_layout.selte

<script>
    import Header from '$lib/global/Header.svelte';
    import Footer from '$lib/global/Footer.svelte';
    import '../styles/c.css'
    import PageTransitions from '$lib/global/PageTransitions.svelte';
    import { navigating } from '$app/stores'; 
</script>

<Header/>

<main>
     <PageTransitions refresh={$navigating}>
     <slot/>
     </PageTransitions>
</main>

<Footer/>

PageTransitions.svelte:

<script>
    import { fly } from 'svelte/transition';
    export let refresh = '';
</script>

{#key refresh}
    <div in:fly="{{ y: 10, duration: 300, delay: 300}}" out:fly="{{ y: 10, duration: 300 }}">
        <slot/>
    </div>
{/key}

Now I need to figure out how to use page transitions to get them working with SrollTrigger, but at least half of my problem has been solvd and I'm already happy. :) :-) 👍

  • Like 6
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...