CSS3 vs jQuery Animations
Introduction
Flash originally paved the way for us to feature more than just text and images on web pages. It allowed developers to include animations and other rich effects on web pages, leading to a much more colourful and varied user experience. However, Flash was plagued by a number of issues like security, long loading times on mediocre networks, etc. Then came JavaScript libraries like jQuery, Prototype and MooTools, which got around a lot of Flash's issues by running natively in the browser, plus they made it easier for the average developer to use JavaScript to create rich effects and animations. Fast forward a few more years, and we've now got animation capabilities available in CSS3, which offers additional advantages, such as potential speed increases due to being rendered directly by the browser.
But what animation solution is really best for us to use? In this article, we shall look at how to create animations in jQuery and CSS3, and how they perform against each other.
Introduction to Animation in jQuery
The jQuery library abstracts a lot of complexity away from the developer. As a case in point, here is how to create a simple <div>
that is animated after a button is clicked.
-
Include the jQuery library in your page, for example:
// It's recommended that you use a CDN to use the jQuery library. Here's a link to Google's CDN: <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js?ver=1.8.1"></script>
-
Create the
<div>
element, and give it some basic style.<div></div>
div { margin-left:10px; margin-bottom:10px; background-color:red; opacity:1; float:left; width:100px; height:1px; }
-
Create the button to click that triggers a function to animate the
<div>
<button id="start">Start Animation</button>
-
Write some jQuery code to select the
<div>
element and apply the effects once the button is clicked. On click, the<div>
's height is increased to 25px and opacity is decreased from 1 to 0.5 over a period of 2000 milliseconds or 2 seconds.$("#start").click(function(){ $("div").animate({ opacity: 0.5, height:"25px", } , 2000); });
It's pretty easy to animate an element with jQuery using very little code, and the best thing about jQuery is that your code will work across older browsers, even as far back as IE6!
Introduction to Animation in CSS3
To create an animation in CSS3, you need to specify two different constructs in your CSS. First of all, you need to specify what form the animation will take using the @keyframes
at-rule, which looks something like this:
@keyframes my-animation {
0% {height:0px; opacity:1; }
100% {height:25px; opacity:0.5; }
}
my-animation
is the name your animation will be identified by, and the different lines are different keyframes. In each case, the properties inside the curly braces say what value the animated properties will have at each stage of the animation, and the percentages dictate how far through the animation each stage is — in this particular case our animation is pretty simple, so we are only defining the start and end of the animation. Then, to apply your animation to an element on your page, you need to refer to it using the animation
property:
div {
margin-left:10px;
margin-bottom:10px;
background-color:red;
opacity:0.5;
float:left;
width:100px;
height:25px;
animation: my-animation 2s;
}
This is functionally identical to the jQuery example earlier: the <div>
is animated over a period of 2 seconds, with its height increasing to 25px and its opacity decreasing from 1 to 0.5. Sounds pretty simple, huh? Unfortunately browser support is not as good for CSS3 animations — IE versions below 10 don't support it, and although all other major browsers support animations well, and the animation spec is now stable, most of them haven't dropped their vendor prefixes yet, so to ensure support just for the moment you'll have to include prefixed versions of the two blocks, for -webkit-
, -moz-
, -ms-
and -o-
. The Opera blocks would look like this, for example:
@-o-keyframes my-animation {
0% {height:0px; opacity:1; }
100% {height:25px; opacity:0.5; }
}
and
div {
...
-o-animation: my-animation 2s;
}
This instantly makes the code base a lot more daunting, although if you wanted to reduce the code back to one block, you could use a solution like a preprocessor. Here are a couple of solutions that you could use to add the right prefix at runtime, or during a site build process:
- SASS — A CSS preprocessor that allows you to include variables, functions, and other features, meaning faster more efficient CSS in some cases. Using SASS shouldn't affect the performance of your site.
- Prefixfree — A JavaScript library that simple adds the right prefixes to your CSS for the browser accessing it, at runtime. This does mean executing more JavaScript on the client machine, which could lead to a slight performance hit, but this should be relatively minor. The downside is that the layout of the webpage will be broken if the user has JavaScript disabled.
So at the moment, it looks like jQuery is the best way to go, especially in terms of browser support. If you want your site to still be usable in older browsers that don't support the animation, it is advisable to make the default settings of the properties that are animated equal to the end state of the animation, for example above you can see that height
is set to 25px and opacity
is set to 0.5, so if the animation isn't available, the element just defaults at its end state. This may be acceptable for your site, or it may not — it really depends on what you are trying to do, and what your client or boss is happy with.
Note: for a lot more detail on CSS animations, read Making a move with CSS3 animations by Chris Mills.
Animation Wars: CSS3 vs jQuery
To test the performance of CSS3 animations against jQuery animations, let's set up a test. We will use the code we have already shown above, but in each case we will animate 300 <div>
s simultaneously, so that it is easier to actually measure the time taken for the animation to run.
CSS3 Animations
The execution graph for the CSS3 animation test looks like Figure 1, which also links through to a larger version of the image for clarity. This graph was created using the Opera Dragonfly profiler tool, and the browser used was Opera 12 on Mac OS X.
Figure 1: The time taken to animate 300 <div>
s with CSS animations.
As seen in Figure 1, the entire animation is completed in around 2.9 seconds.
Next, let's look at memory usage — see Figure 2, which links through to a larger image for clarity. This graph was created using the Memory option inside the Timeline tab of Chrome 21's Developer Tools.
Figure 2: The memory used in animating 300 <div>
s with CSS animations.
The memory used during the CSS3 animation is very small — around 1.5MB, with only about 100 actions required. The final data for this test is:
- Number of actions performed to finish the animation: 100
- Time taken to finish executing the animation: 2.9 seconds
- Memory consumed at the end of the animation: 1.5 MB
Now let us proceed to see how the jQuery animations fare.
jQuery Animations
The execution graph for the jQuery animation test looks like Figure 3, which links through to a larger version for clarity. This graph was created using the Opera Dragonfly profiler tool, and the browser used was Opera 12 on Mac OS X.
Figure 3: The time taken to animate 300 <div>
s with jQuery.
The entire operation takes just over 5 seconds — a much longer time right? The actual animation doesn't take much longer, but there is all the extra overhead of the JavaScript being loaded (notice a slight delay between the button being clicked and the animation starting.) Also, the number of actions performed by the browser is more than 2000, enormous compared to just 100 for the same animation done using CSS3. Even without using developer tools, you will notice that once the 'Start Animation' button is clicked, there is a slight delay before the animation starts.
Now onto memory usage — see Figure 4, which links through to a larger image for clarity. This graph was created using the Memory option inside the Timeline tab of Chrome 21's Developer Tools.
Figure 4: The memory used in animating 300 <div>
s with jQuery.
When it comes to memory, this animation is a lot hungrier, using close to 6 MB! The final data for this test is:
- Number of actions performed to finish the animation: 2119
- Time taken to finish executing the animation: 5 seconds
- Memory consumed at the end of the animation: 6 MB
It is also worth noting that the above animations will give different test results across different browsers on different computers, but at least they provide a usable comparison. Currently, Chrome has the fastest JavaScript processor and executes the jQuery animation a few hundred milliseconds faster than its competitors. However it's an entirely different story when it comes to CSS3 animations. Opera 12 blasts ahead giving a smooth animation, as Opera currently leads the way when it comes to DOM manipulation and processing CSS. Firefox 14 and Safari 6 do a very good job at both the areas. The developer's nightmare, IE (the latest stable version being IE 9) doesn't support CSS3 animations but executes jQuery animations decently.
And the winner is...
CSS3! Clearly, CSS3 wins the race by lengths. The huge difference in performance is because the browser's CSS processor is written in C++ and native code executes very fast whereas jQuery (JavaScript) is an interpreted language and the browser can't predict JavaScript ahead in time, in terms of what event will occur next.
Although the results above indicate that you should use CSS3 for animations, you should bear in mind the advantages and disadvantages we discussed earlier on in the article. You need to keep in mind that a fair amount of people still use Internet Explorer 7 and 8, so you should use jQuery if your animations absolutely need to work the same in those older browsers.
Alternatively, you might be able to live with your animations gracefully degrading in non-supporting browsers, in which case CSS3 animations are the best option.
Note that for simple animations, such as the trivial one shown in this test example, you could probably use less CSS if you did it as a transition instead of an animation. It really is up to you what to use — transitions are quicker to set up but rely on state changes, whereas animations are arguably more flexible and powerful. Choose what is best for your particular situation.
This article is licensed under a Creative Commons Attribution 3.0 Unported license.
Comments
Necroman
Wednesday, September 26, 2012
Mason Brown
Wednesday, September 26, 2012
Another case supporting for CSS animations vs jQuery is that it's helpful to separate "interface design" from "application logic". As a designer/front-end dev, I find it's much easier to hone animations in CSS (presentation), rather than having to manipulate jQuery animations intermingled within the app logic.
sjstrutt
Wednesday, September 26, 2012
The result may still be the same with 1.5.1 vs 1.8.1, but the head-to-head is still deceptive (though I assume this was unintentional).
Chris Mills
Thursday, September 27, 2012
@Mason Brown - yup, certainly makes sense. Although surely even if you are doing both view and controller in JS, you could separate them into different files/directories? Not quite as pure, granted, but even so?
@sjstrutt You are so damn right - I have updated it in the article. I don't know how I missed that...
Jack Doyle
Friday, September 28, 2012
Let's face it: jQuery just isn't optimized for animation.
For relatively simple animations, CSS3 animations (and/or transitions) are great. However, they have some pretty significant limitations that make them ill-suited for a complex professional-grade animation workflow. For example, there are no event callbacks (onComplete, onUpdate, onStart, etc.), easing options aren't nearly as flexible, and what if I wanted to set up a bunch of staggered animations that use different eases (like Elastic.easeOut and Back.easeIn) and then jump to exactly 0.7425 seconds into the sequence and pause? What if I want to build out an entire sequence with overlapping animations and then attach a slider to that, giving the user the ability to zip through it interactively? What if in the middle of the animation, the user clicks a button and I want to smoothly make the entire animation decelerate to half-speed? What if I need to animate along a Bezier path? And of course, as you mentioned, browser support is always an issue with new CSS3 stuff, but JS can much more easily implement workarounds for missing features.
You did a nice job pointing out some of the key factors to consider, and I know you weren't trying to position jQuery as the gold standard in JavaScript animation - I just wanted to point out that the performance of a JS solution doesn't have to be as terrible as jQuery's (no offense to the jQuery folks - I think it's an awesome tool, just not for professional grade animation).
More info about the GreenSock toolset can be found at http://www.greensock.com/v12/
ocampesato
Friday, September 28, 2012
http://code.google.com/p/css3-graphics/
http://code.google.com/p/jquery-css3-graphics/
http://code.google.com/p/css-shaders-graphics/
Adrian Roselli
Saturday, September 29, 2012
Siddharth Rao
Saturday, September 29, 2012
@ocampesato: Thanks :)
Siddharth Rao
Saturday, September 29, 2012
Jack Doyle
Sunday, September 30, 2012
You're absolutely right about jQuery being much more popular than GreenSock right now. Likewise, IE was by far the most popular browser many years ago. Doesn't mean it's better :) Times change. GreenSock is still in beta, yet thousands of developers are using it in major sites like in the latest Batman movie site, MountainDew.com, and many more. Momentum is building.
GreenSock became an industry standard in Flash, and now that it has come to JavaScript (with the same API), there's a good chance it'll do likewise there within a few years. Or not. But either way, I'd encourage folks to take a peek. It's pretty unique and it absolutely destroys jQuery in terms of performance, feature set, flexibility, etc.
Chris Mills
Sunday, September 30, 2012
Constantine Vesna
Sunday, September 30, 2012
p.s: Greensock is very impressive. Animation is smooth and fast.
Siddharth Rao
Monday, October 1, 2012
bobbudd
Monday, October 1, 2012
alberto
Wednesday, October 3, 2012
But, we should use CSS3 for production site? OH LORD NO!
please, we have to keep in mind that we MUST NOT use CSS3 rules for our websites, but just for test. I'm writing this message because i hear around a lots of people who propose their clients HTML5 and CSS3 sites, and i'm asking myself: haven't we spent last 10 years praying for a standard web based on CSS?
Isn't Opera one of the most standard-compliant browser?
So, CSS3 transition will rock, yes, sure, but it WILL rock, in the future!
Michał Biniek
Wednesday, October 3, 2012
Anyway I'm also interested in comparsion CSS3 to Vanilla JS (http://vanilla-js.com/) aka pure JS as sometimes jQuery could make big overhead especially when is caching data (which of course cause bigger memory usage etc but faster access to elements in future actions).
Siddharth Rao
Tuesday, October 9, 2012
Are you the REAL Jack Doyle? ;) I will give GreenSock a try this weekend and something tells me it will win me over :) How in the world could have I missed something this big? I HAVE to spread word about GreenSock, after I try it :)
@bobbudd:
Thanks for opening my eyes, I didn't know that @Jack Doyle IS GreenSock :P
@Alberto:
Many have saved tons of money just by not developing for IE6, 7 and 8! So the future is nearly here and I hope the process only accelerates :) And yes, when it comes to being standard-compliant, Opera rocks!
@Michal Biniek:
You're welcome :) Dragonfly is still a kid, I can't wait to see it grow up. Yes, you are right but then these results might vary in a month or so because JavaScript engines are becoming better and better, to a point where they just can't get any significantly more better. The comparision was to give you an idea that CSS3 is processed faster than JS. You will be able to get a proper result when you design games, that is when the real potential of CSS3 can be seen. :)
Jack Doyle
Thursday, October 11, 2012
Enjoy your test-drive of the GreenSock Animation Platform over the weekend. And you might want to check out the new JavaScript-focused GSAP page launched today: http://www.greensock.com/gsap-js/ - it has a little teaser animation at the top that shows a few capabilities, several of which would be virtually impossible with CSS3 animations.
Happy tweening!
Siddharth Rao
Wednesday, October 17, 2012
Sure thing :) I am giving greensock a round now :) I will get back to you once I have made it bend like Beckham. ;)
mjohnson21
Wednesday, October 24, 2012
The solution is not animating background-position. Instead, animate the position of the element. Framerate improved significantly.