CSS3 Transitions vs. jQuery.animate: The Battle for 60FPS
In early 2011, we are at a crossroads. For years, jQuery.animate() has been the gold standard for adding "flair" to our websites. But as mobile browsers on iPhones and Androids become more prevalent, the performance limitations of JavaScript-based animation are becoming glaringly obvious. The "jank" is real.
Fortunately, the new wave of browsers-Chrome, Safari 5, Firefox 4, and even IE9-are bringing hardware-accelerated CSS3 transitions to the table.
The JavaScript Approach: Timer-Based
jQuery.animate() works by setting a timer (usually via setInterval) and manually updating the inline style of an element every few milliseconds.
// jQuery 1.5 style
$('#box').animate({
left: '+=500',
opacity: 0.5
}, 1000, function() {
console.log('Animation complete');
});
The problem is that JavaScript runs on the UI thread. If the browser is busy parsing HTML or executing other scripts, the timer is delayed. This results in dropped frames. Furthermore, the browser doesn't know an animation is happening, so it can't optimize the rendering pipeline.
The CSS3 Approach: Declarative and Accelerated
With CSS3 transitions, we tell the browser the "start" state and the "end" state, and let the engine handle the interpolation.
/* The box setup */
#box {
position: absolute;
left: 0;
opacity: 1;
-webkit-transition: all 1s ease-in-out;
-moz-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
/* The end state, triggered by a class */
#box.move {
left: 500px;
opacity: 0.5;
}
In JavaScript, we just trigger the class:
document.getElementById('box').className = 'move';
Why CSS Wins in 2011
- Hardware Acceleration: WebKit (Safari/Chrome) can offload CSS animations to the GPU. This is especially critical for mobile devices. By using properties like
transform: translate3d(0,0,0), we can force "compositing layers" that make animations buttery smooth. - Thread Separation: Even if your JavaScript is doing heavy lifting, the browser's compositor thread can often keep the CSS animation running smoothly at 60 frames per second.
- Code Cleanliness: We separate the behavior (JS) from the presentation (CSS).
Handling Callbacks
One area where jQuery still feels "easier" is callbacks. CSS transitions don't have a simple .done() method. Instead, we have to use the transitionend event.
var box = document.getElementById('box');
box.addEventListener('webkitTransitionEnd', function(event) {
console.log('Finished animating: ' + event.propertyName);
}, false);
// Standard (Firefox 4 / IE10 PP)
box.addEventListener('transitionend', function(event) {
// handle completion
}, false);
While the vendor prefixes are a nightmare ( -webkit-, -moz-, -o-), the performance gains are undeniable. If you want your site to feel "App-like" on the new iPhone 4, you need to start moving your animations into your stylesheet.
Aunimeda builds modern web frontends - from single-page applications to complex multi-locale sites.
Contact us to discuss your frontend project. See also: Web Development, Corporate Website Development