Jump to content
GreenSock

TweenLite.lagSmoothing()

TweenLite.lagSmoothing( threshold:Number, adjustedLag:Number ) :

Permits you to control what happens when too much time elapses between two ticks (updates) of the engine, adjusting the core timing mechanism to compensate and avoid "jumps".

Parameters

threshold: Number

Amount of lag (in millisecond) after which the engine will adjust the internal clock to act like the adjustedLag elapsed instead. The lower the number, the more likely (and frequently) lagSmoothing() will be triggered. For example, if the threshold is 500 and the adjustedLag is 33 (those are the defaults), the only time an adjustment will occur is when more than 500ms elapses between two ticks in which case it will act as though only 33ms elapsed. So if the CPU bogs down for 2 full seconds (yikes!), your animations will move 33ms worth of time on the next render instead of jumping a full 2-seconds. Note: this has no affect on the device’s performance or true frame rate – this merely affects how GSAP reacts when the browser drops frames.

adjustedLag: Number

The new (adjusted) amount of time (in milliseconds) from the previous tick. Typically it is best to set this to at least 16 because that’s the normal amount of time between ticks when the engine is running at 60 frames per second. It is more common to set it to at least 33 (which is 2 normal “ticks”). If you set the threshold and the adjustedLag too low, your animations can appear to slow down under heavy pressure. The higher the adjustedLag, the more of a “jump” you’ll see when lagSmoothing kicks in.

Details

Video Explanation

What happens when the CPU gets bogged down and there's a lag between renders? For example, imagine a 2-second tween that should start right away, but the CPU is busy for a full second before it can render that tween for the first time. Most other animation engines (including CSS animations in some browsers) slide the start time forward to compensate but there's a major drawback to that approach: it sacrifices synchronization and can mangle delays so that when you try to neatly stagger animations, they spew out in clumps/groups. That's no good.

GSAP has always used a strict timing model that prioritizes perfect synchronization, meaning in the example above, the tween would render as if it's halfway done after the initial 1-second lag. Basically, every animation engine has to pay the lag tax one way or the other - either maintain strict timing and synchronization, or slide the starting times around and lose sync.

The new TweenLite.lagSmoothing() feature gives you the best of both worlds because when the CPU gets bogged down, it adjusts the core timing mechanism on the next tick which affects all animations, thus everything remains perfectly synchronized. You can set the threshold (in millisecond) so that whenever there's a lag greater than that threshold, the engine will adjust the internal clock to act like the adjustedLag elapsed instead. Even though you call the static method on TweenLite, this one adjustment affects everything in GSAP (tweens, timelines, and delayedCalls because they're all driven by a single timing mechanism at the heart of TweenLite).

For example, if the threshold is 500 and the adjustedLag is 33 (those are the defaults), the only time an adjustment will occur is when more than 500ms elapses between two ticks in which case it will act as though only 33ms elapsed. So if the CPU bogs down for 2 full seconds (yikes!), your animations will move 33ms worth of time on the next render instead of jumping a full 2-seconds. Note: this has no affect on the device's performance or true frame rate - this merely affects how GSAP reacts when the browser drops frames.

This feature is already activated by default, using a threshold of 500ms and a adjustedLag of 33ms, but if you want to change the settings you can do so like this:

//compensate only when 1000ms or more elapses between 2 ticks,
//and then make it act like only 16ms elapsed:
TweenLite.lagSmoothing(1000, 16);

Why not set the values super low, like to 10 for both? Because doing so wouldn't allow much breathing room, and it would naturally make your tweens look like they're running more slowly (because technically they are if the time is getting nudged forward on almost every render). Also note that if you've got any delayedCalls, those will be affected as well. That's a good thing - it ensures that you can rely on those to be perfectly synchronized with the rest of the engine, but if the browser is under heavy pressure and is only rendering a few frames per second, it'd seem as if time is literally slowing down and a 2-second tween (or delayedCall) might actually take 8 seconds to complete.

In most real-world scenarios, the defaults of 500 and 33 are ideal because they protect against significant hiccups in the browser/CPU while allowing minor variations in the frame rate without slowing things down unnecessarily.

If you're using TweenMax, you can access the lagSmoothing() method via TweenMax.lagSmoothing() too.

If you'd like to disable lag smoothing, you can simply set it to 0 like TweenLite.lagSmoothing(0) which is the same as setting the threshold to a super large value so that it never kicks in.

Timing Comparison Demo

Copyright 2017, GreenSock. All rights reserved. This work is subject to theterms of useor for Club GreenSock members, the software agreement that was issued with the membership.
×