GPU Accelerating your CSS Animations

Bring Beautiful, Smooth CSS Animations to Life

by James Futhey — Posted in CSS / Animation on Thursday, July 24, 2014

Tagged: GPU, jQuery, Translate3d, Acceleration, Animation, CSS, Velocity.js

Why do we need GPU acceleration?

Many CSS animations, especially those that affect margin sizes, require massive amounts of the screen to be repainted for each and every frame that is generated. Worse, moving larger items or adjusting margins through CSS animations sometimes requires offscreen data to be recalculated as well. This can become overwhelming for our general purpose CPU thread, which is already doing the heavy lifting of rendering one or more pages, and running increasingly extensive amounts of JavaScript. And for technical reasons I won't get into, a general-purpose computing device such as the CPU is not well-suited for this task to begin with.

The Solution? GPU Acceleration

Increasingly, more and more PCs and Mobile devices, even on the low-end, are being shipped with powerful GPUs accessible by most modern browsers (including IE 10+!). These are the same chips capable of rendering complex animation for 2d and 3d gaming, and typically, when you're browsing the internet, they go completely unused. The browser, by default, does not make use of this hardware for most animations. Worse, even with only a few objects being animated, your CSS animations can bring your webpage to a crawl, cause frame-skipping, and just turn out to be super ugly. So, in many cases, you'll want to force GPU-accelerated animation.

But I heard this is why CSS animation is already faster than JavaScript animation.

Yes and no. Some browsers, such as firefox, perform a limited amount of GPU accelerated animation automatically. However, a majority of browsers (Webkit & IE) do not perform GPU acceleration on any 2d animations (transform, translate, scale, skew, rotate, etc). For other reasons, CSS animations rendered by the browser have had smoother performance than animations handled by JavaScript looping, such as jQuery.animate(), and this has led to the perception that CSS animations are always faster than those in JavaScript. Not only is this not true, but there are many limitations to what you can animate in CSS alone, and JavaScript events can be useful triggers for animations which can delight webpage visitors, and should not be dismissed.

A majority of my animations in CSS are 2d. Most browsers do not GPU accelerate 2d animations, how do I increase performance?

A trick you can use to enable GPU acceleration on your webpages is to first apply a 3d transform (which does nothing) to your elements. You want to apply this to all elements, not just the elements you wish to apply 2d css animations to, because your animation may still cause these elements to be repainted by the browser. Look at the example CSS below:

* {
    -webkit-transform: translate3d(0px,0px,0px);
    -moz-transform: translate3d(0px,0px,0px);
    -ms-transform: translate3d(0px,0px,0px);
    -o-transform: translate3d(0px,0px,0px);
    transform: translate3d(0px,0px,0px);

It performs a 3d translate function on each element of the DOM, which forces the browser to enable rendering (for that element) using the GPU. Now, when we apply 2d animations to that DOM element, it's changes will be rendered by the GPU, not the CPU, increasing performance on all modern browsers and devices (even IE!). This not only applies to CSS animations, but to JavaScript animations as well, since we are in essence forcing the GPU to render our elements each time the screen is repainted.

However, this does not solve the root issue with using the jQuery.animate() function. That issue is not primarily caused by the CPU overhead of repainting our screen, since even trivial jQuery animations are affected. jQuery.animate() performs slowly because the jQuery loop itself is rather slow, as evinced by the slowness of other jQuery functions, such as dom element lookup and the jQuery.each() function. However, other libraries, such as velocity.js, can be used as a replacement for the jQuery.animate() function to provide much smoother animation.

category: CSS
subcategory: Animation
subtitle:Bring Beautiful, Smooth Animations to Life




James Futhey 


Apparition Theme
Thoughts, stories and ideas.