greensock / GSAP

GSAP (GreenSock Animation Platform), a JavaScript animation library for the modern web
https://gsap.com
19.56k stars 1.72k forks source link

TweenLite.set seems to do a lot more than it should #51

Closed fregante closed 10 years ago

fregante commented 10 years ago

I remember seeing GSAP reading and then writing CSS values even when I thought it was unnecessary, like with TweenLite.set(el, {opacity: 0.5}), so I wanted to investigate.

What I found was a much worse situation than imagined. Try this pen and open Chrome's Timeline view, it's a simple two-button demo that toggles a transform on the clicked element. I used plain event listeners to avoid any possible jQuery noise.

var gset = false;
document.getElementById('gsap').onclick = function() {
  TweenLite.set(this, {scale: gset?1:2});
  gset = !gset;
};
var dset = false;
document.getElementById('cssom').onclick = function() {
  this.style.transform = 'scale('+(dset?1:2)+')';
  dset = !dset;
};

The CSSOM activity is plain and simple:

CSSOM activity

TweenLite instead generates dozens of animationFrames, composite calls and a few paints, it doesn't fit in a single screenshot:

TweenLite activity

I figured TweenLite has to do more behind the scenes than any direct CSSOM call, but all that activity might be a bit too much and is probably unintended.

jackdoyle commented 10 years ago

I can totally understand why those timeline entries would seem odd and cause you to suspect that GSAP is doing too much, but it's rather misleading. Let me explain...

The main ticker that drives GSAP runs on the requestAnimationFrame API in modern browsers - that's why you see all those "Animation Frame Fired" entries. Those are completely normal and they use almost no resources. You can set up your own requestAnimationFrame loop and even if you do ABSOLUTELY NOTHING inside that function/loop, it'll still spew out those timeline entries, once for each time requestAnimationFrame fires. Again, these are very cheap calls and the core engine needs the loop to be running in order for it to operate effectively. Also keep in mind that GSAP automatically powers down after a few seconds of inactivity, shutting off its requestAnimationFrame loop (unless you register a "tick" event listener in which case it shouldn't turn off).

Also keep in mind that a set() call must also read and record the current values before it sets the new ones in order to accommodate reversion (like if you place that set() tween into a timeline that gets reversed). So there's more processing required when you're doing a read/write cycle rather than just a write.

Rest assured that GSAP is EXTREMELY optimized and we're about to release an update that makes it even faster (particularly with the read/write cycles).