CSS3 vs jQuery Animations

By Siddharth Rao

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.

  1. 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>
  2. 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;
    }
  3. Create the button to click that triggers a function to animate the <div>

    <button id="start">Start Animation</button>
  4. 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:

  1. 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.
  2. 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.

Image illustrating the time taken to animate 300 divs with CSS animations in Opera 12

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.

Image illustrating the heap memory used to animate 300 divs with CSS animations in Chrome 21

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.

Image illustrating the time taken to animate 300 divs with jQuery in Opera 12

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.

Image illustrating the heap memory used to animate 300 divs with jQuery in Chrome 21

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.

I tweet around as @awesomesid :)


This article is licensed under a Creative Commons Attribution 3.0 Unported license.

Comments

  • photo

    Necroman

    Wednesday, September 26, 2012

    When speaking of animations, what about supporting http://www.w3.org/TR/animation-timing/#requestAnimationFrame ?
  • photo

    Mason Brown

    Wednesday, September 26, 2012

    NIce read. CSS for the win!

    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.
  • photo

    sjstrutt

    Wednesday, September 26, 2012

    Why are you measuring performance using an arbitrary (and old) version of jQuery (1.5.1, released February 2011), rather than the current version? The current version is 1.8.2 (and if you insist on using the latest on Google's CDN, use 1.8.1).

    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).
  • photo

    Chris Mills

    Thursday, September 27, 2012

    @Necroman - last I heard, we were working on it. I'll have a dig and see if I can find any updates.

    @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...
  • photo

    Jack Doyle

    Friday, September 28, 2012

    Great points, although I worry that jQuery gives JavaScript animation a bad rap. The GreenSock Animation Platform, for example, is not only MUCH faster than jQuery (not even close), but it even beats out Zepto's CSS3-based transitions (at least on all the devices I've tested). Here's a simple interactive tool that lets you compare performance among jQuery, Dojo, YUI, MooTools, TweenJS, Zepto and GreenSock's TweenLite: http://www.greensock.com/js/speed.html

    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/
  • photo

    ocampesato

    Friday, September 28, 2012

    You might enjoy some of these eye-candy code samples:
    http://code.google.com/p/css3-graphics/
    http://code.google.com/p/jquery-css3-graphics/
    http://code.google.com/p/css-shaders-graphics/
  • photo

    Adrian Roselli

    Saturday, September 29, 2012

    The link to the jQuery animation test is 404.
  • photo

    Siddharth Rao

    Saturday, September 29, 2012

    @Adrian: I just noticed that. I will let you know once the link's working.

    @ocampesato: Thanks :)
  • photo

    Siddharth Rao

    Saturday, September 29, 2012

    @Jack Doyle:Greensock is totally cool. But let's face the truth, only a few thousand developers would be aware of that platform, whereas nearly 50% of the websites use jQuery in some way or the other. jQuery is the go to JavaScript library and talk about animations, jQuery will be the first thought in a developer's mind. CSS3 is still an infant but it is very promising and one can learn how to implement just by taking a glance at it. It also works for the users that have disabled JavaScript. Given that the browsers are getting faster and faster in processing JavaScript, there will be a day when jQuery animations will be lighter and faster and the gap between CSS3 and jQuery animations will only reduce. And does GreenSock support IE6 and IE7?
  • photo

    Jack Doyle

    Sunday, September 30, 2012

    Yep, GreenSock supports IE6 and IE7. In fact, you can even rotate, skew, and scale things and use transformOrigin in those old browsers! Try that with jQuery :)

    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.
  • photo

    Chris Mills

    Sunday, September 30, 2012

    Link to jQuery animation example fixed. Sorry about that folks!
  • photo

    Constantine Vesna

    Sunday, September 30, 2012

    Don't want to sound like a party-pooper, but - our tests in May showed that CSS3 transitions are actually slower and uglier than jQuery animations ... We were animating top, left and background-position properties. For opacity - maybe css is faster now, but you must check it for yourself.

    p.s: Greensock is very impressive. Animation is smooth and fast.
  • photo

    Siddharth Rao

    Monday, October 1, 2012

    @Constantine Vesna: Can you please give me the source code or send me a link where I can see those animations? I would love to take a look :)
  • photo

    bobbudd

    Monday, October 1, 2012

    I love GreenSock, been using it in flash since '03, looking forward to seeing what it can do in JS - but in the interests of full disclosure, Jack Doyle IS greensock.
  • photo

    alberto

    Wednesday, October 3, 2012

    Is CSS3 a faster and a better way then jquery/javascript, ecc... animation? Yes, sure it is. Is CSS3 a better mobile-friendly language then other client-side languages? Yes it is, and i can understand why Google, Apple and Telenor are supporting it. Ok, everything is good, and Opera developers are doing a great job writing tutorials.
    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!
  • photo

    Michał Biniek

    Wednesday, October 3, 2012

    Thank you for this really nice comparsion - and also presentation of new debugging parts in dragonfly. However I'm not sure if memory profiler in chrome should be really used here - at least comparing usage of memory in memory profiler and on task manager sometimes generates completely different (as memory usage in profiler is close connected to js process not other internal stuff especially not images).
    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).
  • photo

    Siddharth Rao

    Tuesday, October 9, 2012

    @Jack Doyle:

    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. :)
  • photo

    Jack Doyle

    Thursday, October 11, 2012

    Ha ha - yes, I'm the "real" Jack Doyle. Dang, my cover is blown.

    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!
  • photo

    Siddharth Rao

    Wednesday, October 17, 2012

    Haha :) I was so successful :P

    Sure thing :) I am giving greensock a round now :) I will get back to you once I have made it bend like Beckham. ;)
  • photo

    mjohnson21

    Wednesday, October 24, 2012

    Hey Constantine, we discovered the same thing when trying to animate background position. It performs poorly, and IIRC was causing redraws at every frame.

    The solution is not animating background-position. Instead, animate the position of the element. Framerate improved significantly.
No new comments accepted.