Jump to content
Search Community

TweenMax Maximum Call Stack Size Exceeded

Guest s.sottocorna
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Guest s.sottocorna

Hello,

Me and my team are experiencing a persisting bug in our game, which we aren't sure if it's a GSAP bug? 

If you globally pause all tweens when a tween, whose timescale is being handled by another tween, is active, you receive a maximum call stack size exceeded error. Please see the attached pen with the console active

Is there a mistake on our part?

See the Pen PKWdRO by ssottocorna (@ssottocorna) on CodePen

Link to comment
Share on other sites

Guest s.sottocorna

After lurking a bit more, I discovered this 

which prevents the bug from spamming call stack errors, however it still does not fix the issue completely, as it generates strange values and causes flickering.  

Capture.PNG

Link to comment
Share on other sites

Guest s.sottocorna

We have linked the ticker of EaselJS with the ticker of TweenMax to achieve a better synchronization and allow for slow-mo effects by manipulating the global timescale.

Link to comment
Share on other sites

Short answer:

After many hours of tracking this down, I've got a solution in place. You can preview the next release (1.20.3) (uncompressed) at https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/TweenMax-latest-beta.js - I think you'll find that resolves things. Please let me know if you notice anything else odd. 

 

Long answer:

It had to do with a very tricky scenario where you've got two tweens in the same timeline, one of which is reducing the other's timeScale which in turn makes it stretch out duration-wise on its parent timeline and its start time must be shifted backwards to keep the playhead aligned. But TimelineLite/Max instances cannot contain child animations with NEGATIVE start times (for many reasons...I'll spare you the explanation). To fix those negative start times, it shifts all the child animations forwards and the timeline's startTime backwards by the same amount (thus aligning the playhead). 

 

In this case, the in the same rendering cycle, one tween was affecting the startTime of another which shifted the timeline as well, and we had some performance optimizations in place that avoid doing certain calculations until absolutely necessary, and this particular scenario wasn't factored into those conditions. Extremely rare, but I'm glad you stumbled upon it and let us know. Again, it should be resolved now. It'd only show up when you've got two tweens in a timeline, one of which has its timeScale being slowed down so much that its startTime goes backward beyond 0. Sorry about any inconvenience, and thanks for being patient. 

 

Oh, and thanks for the reduced test case! Extremely helpful in figuring out what was going on. I wish everyone was as thorough and provided codepens like that when they encounter a problem. :)

  • Like 3
Link to comment
Share on other sites

Guest s.sottocorna

Thank you very much for the prompt response! We will test the solution thoroughly and report if we encounter any more issues.

Link to comment
Share on other sites

  • 2 months later...
Guest s.sottocorna

@GreenSock

During our stress tests we encountered a very similar problem. 

 Capture.PNG.ba04108ee1fb582cd2e93ab9c6954484.PNG

 

This is simply caused by stopping and resuming all tweens a bunch of times - in this case 4735 times, but I suspect it's application and device specific.

Here is the codepen with the steps:

 

See the Pen boKabM by ssottocorna (@ssottocorna) on CodePen

 

I suspect this is caused by this while loop:

 


		p._hasPausedChild = function() {
			var tween = this._first;
			while (tween) {
				if (tween._paused || ((tween instanceof TimelineLite) && tween._hasPausedChild())) {
					return true;
				}
				tween = tween._next;
			}
			return false;
		};

 

This is reproducible in our games by simply keeping CTRL + tab pressed on chrome and waiting some time.

 

Interestingly, if this keeps going for a while, we receive a different call stack error in our games, from the p.render function in TweenMax.

image.png.c430b67ed2fa5d7934a7a330a5977476.png

 

 

Link to comment
Share on other sites

Hm, from what I can tell, this [probably] isn't a bug. The issue is that you're calling exportRoot() literally 100,000 times and each time, it basically wraps all the animations on the root timeline into a TimelineLite. So you've got things nested 100,000 levels deep. The browser is assuming this is a recursion error simply because there are so many calls to one function. 

 

For example, the first time you call exportRoot(), it wraps everything. The next time, the only thing on the root timeline is that previously exported stuff in a TimelineLite, thus it wraps THAT TimelineLite inside a TimelineLite and returns that. Same with the next time you call exportRoot(), and so on. Therefore, when the root timeline's render() method gets called, it loops through its children and calls their render() methods accordingly, and those do the same to their children, and so on. That's exactly how it's designed to work. But notice that the TimelineLite.prototype.render() method is getting called a ton of times in a row. 

 

One way to avoid this is to add some logic to avoid excessive nesting. Maybe dump them all out of your exported root before you call exportRoot() again, like:

//De-nest things from the "allTweens" exported root...
if (allTweens) {
    var animations = allTweens.getChildren(),
        startTime = allTweens.startTime(),
        root = allTweens.timeline,
        l = animations.length,
        i;
    for (i = 0; i < l; i++) {
        root.add(animations[i], animations[i].startTime() + startTime);
    }
    allTweens.kill();
}
allTweens = TimelineLite.exportRoot();
...

 

Does that help? 

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