Animation Speed in JavaScript and CSS

In this article, we go through how JavaScript-based DOM animation libraries, such as Velocity.js and GSAP, are more efficient than jQuery and CSS-based animation libraries. We will discuss how those libraries work, where to use them and what other alternatives are out there for animation.

jQuery

Let’s start with the basics: JavaScript and jQuery are falsely conflated. JavaScript animation is fast. jQuery slows it down. Why? obvious, despite jQuery being tremendously powerful, it was never the goal of its designers for jQuery to be an efficient animation engine:

Note that layout thrashing is what causes stuttering at the start of animations, garbage collection is what causes stuttering during animations, and the absence of RAF is what generally produces low frame rates.

DOM queries and DOM updates

Queries that take place after an update force the browser to recalculate the page’s computed style data (while taking the new update’s effects into consideration). This produces significant overhead for animations that are running over tiny intervals of just 16ms.

Avoiding layout thrashing consists of simply batching together DOM queries and DOM updates:

JS Bin on jsbin.com

Implementing RAF doesn’t require a massive refactoring to your existing codebase. Let’s compare the basic implementation of RAF against that of setInterval:

JS Bin on jsbin.com

RAF makes a huge boost to animation performance that you could make with a single change to your code.

CSS Transitions

CSS transitions unlike jQuery, offloads animation logic to the browser itself, which makes it efficient by

  1. optimizing DOM interaction and memory consumption to avoid stuttering,
  2. leveraging the principles of RAF under the hood and
  3. forcing hardware acceleration (leveraging the power of the GPU to improve animation performance).

The reality, however, is that these optimizations can also be performed directly within JavaScript. GSAP has been doing it for years. Velocity.js, a new animation engine, not only leverages these same techniques but also goes several steps beyond — as we’ll explore shortly.

The JavaScript animation can be faster than CSS animation libraries:

Let’s find out the weaknesses of the CSS animation libraries.

  • Transitions’ forced hardware acceleration intensifies GPU’s, resulting in stuttering and banding in high-stress situations. These effects are exacerbated on mobile devices. (Specifically, the stuttering is a result of the overhead that occurs when data is transferred between the browser’s main thread and its compositor thread. Some CSS properties, like transforms and opacity, are immune to this overhead.) Adobe elaborates on this issue here.
  • Transitions do not work below Internet Explorer 10, causing accessibility problems for desktop sites since IE8 and IE9 remain very popular.
  • Because transitions aren’t natively controlled by JavaScript (they are merely triggered by JavaScript), the browser does not know how to optimize transitions in sync with the JavaScript code that manipulates them.

JavaScript-based animation libraries can decide for themselves when to enable hardware acceleration, they inherently work across all versions of IE, and they’re perfectly suited for batched animation optimizations.

If you are exclusively developing for mobile and your animations consist solely of simple state changes, you will be better off using raw CSS transitions . In such circumstances, transitions are efficient and native that allow you to retain all animation logic inside your stylesheets and avoid bloating your page with JavaScript libraries. If you’re designing intricate UI flourishes or are developing an app with a stateful UI, always use an animation library so that your animations remain efficient and your workflow remains manageable. One such library that does a great job at managing CSS transitions is Transit.

JavaScript Animation

So as you see, JavaScript can have the upper hand when it comes to performance. But exactly how much faster can JavaScript be?

Velocity

How exactly does JavaScript reach its high levels of performance? Below is a short list of optimizations that JavaScript-based animation is capable of performing:

  • Synchronizing the DOM → tween stack across the entirety of the animation chain in order to minimize layout thrashing.
  • Caching property values across chained calls in order to minimize the occurrence of DOM querying (which is the Achilles’ heel of performant DOM animation).
  • Caching unit conversion ratios (e.g. px to %, em, etc.) across sibling elements in the same call.
  • Skipping style updating when updates would be visually imperceptible.

Revisiting what we learned earlier about layout thrashing, Velocity.js leverages these best practices to cache the end values of an animation to be reused as the start values of the ensuing animation — thus avoiding requerying the DOM for the element’s start values:

JS Bin on jsbin.com

In the above example, the second Velocity call knows that it should automatically start with an opacity value of 1 and a top value of 50%.

The browser can perform most of these same optimizations itself, but it can limit the ability of the developer to do so. Hence why jQuery doesn’t use RAF, browsers would never impose optimizations that have even a tiny chance of breaking spec or deviating from expected behavior.

GSAP

Finally, let’s compare the two JavaScript animation libraries (Velocity.js and GSAP) against one another.

  • GSAP is a fast, richly-featured animation platform. Velocity is a lightweight tool for drastically improving UI animation performance and workflow.
  • GSAP requires a licensing fee for various types of businesses. Velocity is freely open-sourced via MIT license.
  • Performance-wise, GSAP and Velocity are similar in real-world projects.

Ideally, you should use GSAP when you require precise control over timing (e.g. remapping, pause/resume/seek), motion (e.g. bezier curve paths), or complex grouping/sequencing. These features are crucial for game development and certain niche applications, but are less common in web app UI’s.

Velocity.js

JS Bin on jsbin.com

Referencing GSAP’s rich feature set is not to imply that Velocity itself is light on features. To the contrary. In just 7Kb when zipped, Velocity not only replicates all the functionality of jQuery’s $.animate(), but it also packs in color animation, transforms, loops, easings, class animation, and scrolling.

In short, Velocity is the best of jQuery, jQuery UI, and CSS transitions combined.

Further, from a convenience viewpoint, Velocity uses jQuery’s $.queue() method under the hood, and thus interoperates seamlessly with jQuery’s $.animate(), $.fade(), and $.delay() functions. And, since Velocity’s syntax is identical to $.animate()‘s, none of your page’s code needs to change.

If you take a quick look at Velocity.js. At a basic level, Velocity behaves identically to $.animate():

JS Bin on jsbin.com

At its most advanced level, complex scrolling scenes with 3D animations can be created — with merely two simple lines of code:

JS Bin on jsbin.com

Summary

Head on over to VelocityJS.org to learn more.

So remember that there is about more than just choosing the right animation library

.

Be first to comment

Leave a Reply