Animating content can be a contentious subject, particularly if jQuery or JavaScript is used—if we were to take a straw poll of 100 people and ask which they used, it is very likely that we would get mixed answers! A key answer of it depends is likely to feature at or near the top of the list of responses; many will argue that animating content should be done using CSS, while others will affirm that JavaScript-based solutions still have value.
Leaving aside that…shall we say…lively debate, if we're looking to move away from using jQuery, and in particular .animate(), then we have some options available to us:
• Upgrade your version of jQuery! Yes—this might sound at odds with the theme of this chapter, but the most recent versions of jQuery introduced the use of requestAnimationFrame, which improved performance, particularly on mobile devices.
• A quick and dirty route is to use the jQuery Animate Enhanced plugin, available from http://playground.benbarnett.net/jquery-animate-enhanced/; although a little old, it still serves a useful purpose. It will (where possible) convert .animate() calls into CSS3 equivalents; it isn't able to convert all, so any that are not converted will remain as .animate() calls.
• Using the same principle, we can even take advantage of the JavaScript animation library, GSAP—the Greensock team have made available a plugin (from https://greensock.com/jquery-gsap-plugin), that replaces jQuery.animate() with their own GSAP library. The latter is reputed to be 20 times faster than standard jQuery! With a little effort, we can look to rework our existing code—in place of using .animate(), we can add the equivalent CSS3 style(s) into our stylesheet and replace existing calls to .animate() with either .removeClass() or .addClass(), as appropriate.
• We can switch to using libraries such as Transit (http://ricostacruz.
com/jquery.transit/), it still requires the use of jQuery, but gives better performance than using the standard .animate() command.
• Another alternative is Velocity JS by Jonathan Shapiro, available from http://julian.com/research/velocity/; this has the benefit of not having jQuery as a dependency. There is even talk of incorporating all or part of the library into jQuery, as a replacement for .animate()—for more details, check out the issue log at https://github.com/jquery/jquery/
issues/2053.
Many people automatically assume that CSS animations are faster than JavaScript (or even jQuery). After all, we don't need to call an external library (jQuery); we can use styles that are already baked into the browser, right? The truth is not as straightforward as this—in short, the right use of either will depend on your requirements and the limits of each method. For example, CSS animations are great for simple state changes, but if sequencing is required, then you may have to resort to using the JavaScript route.
The key, however, is less in the method used, and more in how many frames per second are displayed on screen. Most people cannot distinguish above 60FPS—this produces a very smooth experience. Anything less than around 25FPS will produce blur and occasionally appear jerky—it's up to us to select the best method available, that produces the most effective solution.
To see the difference in frame rate, take a look at https://frames-per-second.appspot.com/—the animations on this page can be controlled; it's easy to see why 60FPS produces a superior experience!
So, which route should we take? Well, over the next few pages, we'll take a brief look at each of these options. At this point, you may well be asking, "How is this relevant to PostCSS though, given that this is the subject of this book?"
In a nutshell, they are all methods that either improve how animations run, or allow us to remove the dependency on .animate(), which we know is not very efficient!
True, some of these alternatives still use jQuery, but the key here is that your existing code could be using any or a mix of these methods. Later in this chapter, we'll
take a look at how we can begin to remove jQuery, and focus more on using CSS3 animations, using the PostCSS plugin system.
A small word of note, all of the demos over the next few pages were run at the same time as a YouTube video was being run; this was to help simulate a little load and get a more realistic comparison. Running animations under load means less graphics processing power is available, which results in a lower FPS count.
Let's kick off with a look at our first option, the Transit.js library.
Animating content with Transit.js
In an ideal world, any project we build will have as few dependencies as possible;
this applies equally to JavaScript or jQuery-based content as it does to CSS styling.
To help with reducing dependencies, we can use libraries such as TransitJS or Velocity to construct our animations. The key here is to make use of the animations that these libraries create, as a basis for applying styles we can then manipulate using .addClass() or .removeClass(). To see what I mean, let's explore this concept with a simple demo:
1. We'll start by opening up a copy of animate.html—to make it easier, we need to change the reference to square-small from a class to a selector:
<div id="square-small"></div>
2. Next, go ahead and add in a reference to the Transit library, immediately before the closing </head> tag:
<script src="js/jquery.transit.min.js"></script>
3. The Transit library uses a slightly different syntax, so go ahead and update the call to .animate() as indicated:
smallsquare.transition({x: 280}, 'slow');
Save the file, then try previewing the results in a browser—if all is well, we should see no material change in the demo:
However, the animation will be significantly smoother—the frame count is higher, at 44.28FPS, with fewer dips:
Let's compare this with the same profile screenshot taken for the Revisiting basic animations section, earlier in this chapter—notice anything?
Profiling browser activity can be complex, but there are only two things we need to concern ourselves with here: the FPS value and the state of the green line. The FPS value, or Frames Per Second, is over three times higher, and for a large part, the green line is more consistent, with fewer, more short-lived dips.
This means that we have a smoother, more consistent performance; at approximately 44FPS, the average frame rate is significantly better than using standard jQuery—but we're still using jQuery!
There is a difference, though—libraries such as Transit or Velocity convert animations, where possible, to CSS3 equivalents—if we take a peek under the covers, we can see this in the flesh:
We can use this to our advantage, by removing the need to use .animate() and simply use .addClass() or .removeClass()—we'll see this in action later in this chapter, in the Switching classes using jQuery section.
If you would like to compare our simple animation when using Transit or Velocity, there are examples available in the code download, as demos T35A and T35B, respectively.
To take it to the next step, we can use the Velocity library to create a version of our demo using plain JavaScript—we'll see how as part of the next demo. Beware though—this isn't an excuse to still use JavaScript; as we'll see, there is little difference in the frame count!