At one time, most developers used jQuery to animate elements in the browser. Let this fade, let that enlargement, very simple. As interactive projects become more complex and mobile devices increase in number, performance becomes increasingly important. Flash is abandoned, and talented animation developers use HTML5 to achieve results that have never been achieved in the past. They need better tools to develop complex animation sequences and get the best performance. JQuery can't do that. As the browser matures, it also begins to offer some solutions.
The most widely accepted scenario is the use of CSS animations (and transitions). Over the years, it has become a hot topic in the industry, and in various seminars, "hardware acceleration" and "mobile-friendly" are always heard. JavaScript-based animations are always treated as outdated or even "dirty." But is that really the case?
As a person fascinated by animation and performance, I eagerly invested in the embrace of CSS, but when I began to find some big problems, I did not go into the study. I was shocked.
This article is used to reveal some of the major flaws in CSS-based animations, so you can avoid the problems that have plagued me, and also teach you to decide when to use JS animations and when to use CSS animations.
Lack of independent scale/rotation/position control
Animating the dimensions, rotations, and positions of elements is very common. In CSS, these settings are plugged into transform
attributes so that they are not really controlled independently. For example, how do you use different time and easing functions to control element rotation
and attribute separately scale
? Maybe this element will keep shaking and you want to spin it. This can only be achieved with JavaScript.
See the Pen independent Transforms by Greensock (@GreenSock) on Codepen.
In my opinion, this is a very significant problem with CSS animations, but if you only need to develop some simple animation effects that trigger the entire Transform state at the same time, it's not a big problem.
Performance features
Most comparisons compare CSS animations with jquery because the use of jquery is very common (as if JavaScript and jquery are synonyms). But JQuery's animation performance is poor and well known. The newer GSAP is also JavaScript-based, but it is no exaggeration to say that its performance is nearly 20 times times higher than that of jQuery. So, part of the reason that JavaScript animations are notorious is that I think jQuery.
The reason for using CSS animations is that the concept of "hardware acceleration" is often mentioned. It sounds big, doesn't it? Let's break it down into two parts:
Use of the GPU
The GPU is optimized for performing similar control pixel moves and applying transformation matrices and transparency, so modern browsers will try to transfer this task from the CPU to the GPU. The trick is to separate the animated elements and build your own GPU layer, because as long as a layer is created, it's easy to let the GPU move those pixels and combine them. Unlike counting the locations of each pixel at 60 times per second, the GPU can store a lot of pixels, and then we can manipulate the pixels by moving the pixel up by 10 pixels and moving it down by 5 pixels.
Note: The GPU is limited in image storage space, so it is inappropriate to convert each element to a single layer. Once the GPU has run out of storage space, the speed is drastically reduced.
Declaring animations through CSS allows the browser to decide which element should get the GPU layer and allocate resources according to the actual situation. Very convenient.
* * But do you know you can do the same thing with JavaScript? * * Use a 3D feature trigger (for example, translate3d()
or matrix3d()
) to let the browser create a GPU layer for this element. So GPU acceleration is not just for CSS animations, but JavaScript animations are just as beneficial!
Also remember that not all CSS properties can get GPU acceleration in CSS animations. In fact, most of them are not. Transformations (such as scale,rotation, translation, and skew) and transparency effects are directly beneficial. So don't take it for granted that you just use CSS animations and all the effects get the help of the GPU, which is wrong.
Transfer the calculation to a different thread
Another aspect of hardware acceleration is the use of different threads of the CPU for animation-related calculations. Again, it sounds beautiful in theory, but it's actually not about the cost of performance, and developers tend to overestimate the benefits.
First, only properties that are independent of the document flow can actually be handed over to another thread. So again, transformation and transparency are the primary beneficiaries. There is also overhead in the process of transferring threads. In most animations, the rendering of images and the presentation of documents have consumed most of the processor's resources (which has not been counted as a resource for the intermediate animation properties themselves), so the benefits of transferring threads are negligible. For example, in an animation, 98% of the resources are used to calculate the rendering of the image and the presentation of the flow of the document, only 2% of the resources used to calculate the location, rotation, transparency and other properties, even if you will calculate this part of the speed of 10 times times, the overall speed increase may be only 1%.
Performance comparison
The following stress tests create a certain number of image elements (points), and use animations to let them fly from point to edge in random directions with random delay, showing a flying particle effect. Increase the number of particles and observe the comparative effect of JQUERY,GSAP and Zepto. Since Zepto uses CSS to show all the animations, should it perform best?
See the Pen speed Test:gsap vs CSS transitions (zepto) vs JQuery by Greensock (@GreenSock) on Codepen.
The result confirms most of the online conclusion that CSS animations are significantly faster than jQuery. However, on most of the devices and browsers I tested, GSAP's performance was even better than CSS (in some cases, it was a big gap, such as GSAP on Microsoft Surface RT 5 times times faster than CSS animations created by Zepto, and on IPad 3 GSAP on IOS 7 also has a faster animation transform than the CSS transition.
Animated Properties |
Better W/javascript |
Better w/css |
Top, left, width, height |
Windows Surface RT, IPhone 5s (iOS7), ipad 3 (IOS 6), ipad 3 (iOS7), Samsung Galaxy Tab 2, Chrome, Firefox, Safari, Opera, Kindle Fire HD, IE11 |
(none) |
Transforms (Translate/scale) |
Windows Surface RT, IPhone 5s (iOS7), IPad 3 (iOS7), Samsung Galaxy Tab 2, Firefox, Opera, IE11 |
IPad 3 (iOS6), Safari, Chrome |
How fast is it? In the initial version of the test, there was a measurement of the number of frames per second, but it was soon discovered that there was no accurate way to measure FPS values across browsers, especially CSS animations. And the particular browser gets a misleading number, so I removed it. You can do indirect measurements, such as gradually increasing the number of particles, switching between different animation engines, observing the rendering quality of the animation (smooth and stable movement, high dispersion of particles, etc.). After all, our goal is to make the animation look good.
Some interesting things:
- JavaScript can perform better (GSAP, not jQuery) when applying animated properties that affect document flow, such as top/left/width/height values.
- Some devices appear to be optimized for the transiforms transformation, while others deal with top/left/width/height changes better. In particular, the old iOS6 is better at handling CSS animation transformations, while the updated iOS7 system has regressed in this respect, and now it is noticeably slower.
- There is a noticeable delay when the CSS animation has just started, because the browser has to compute the layer and transfer the data to the GPU, and JavaScript-based animations have the same problem. So, "GPU acceleration" also has its own overhead. (Translator Note: This issue can be resolved by the new CSS properties
will-change
, related documents)
- When the pressure is larger, the particles created by the CSS transform are sprayed in a similar banded or annular form (which seems to be the problem of synchronous timing, which is caused by different threading processes).
- In some browsers (like Chrome), when the number of particles in the animation is very high, the transparency of the text disappears completely, but only in CSS animations!
Although optimized JavaScript animations are often as fast or faster as CSS animations, CSS handles 3D transformations faster, but this is also related to how the browser handles the 16-element matrix today (forcing numbers to be converted to concatenated strings and then to numbers). Fortunately this situation will change and you will not feel this difference in most practical projects.
I encourage you to use your own tests in your project to find the best way to achieve the most performance animations. Do not believe that CSS animation performance is high, and do not let the above test affect your own application results. Be sure to test, test, and test yourself.
Run-time Controls and events
Some browsers allow you to pause in CSS keyframes animations, but most of all. You cannot find a specific point in the animation, it is impossible to reverse the painting halfway, it is impossible to change the time scale, it is impossible to add a callback function in a particular location, or to bind them to a lot of playback events [?]. JavaScript provides a great way to control, see the following example:
See the Pen impossible with Css:controls by Greensock (@GreenSock) on Codepen.
Most modern animations value interactivity, so it's especially useful to animate from a variety of starting variables (for example, perhaps based on where the user clicked the mouse), or to change the elements that are moving, and the pre-declarative CSS animations do not.
Work flow
CSS transforms are useful for simple switching between two states, such as flipping or expanding a menu. For animations of continuous transform states, you need to use CSS keyframes animations, which force you to declare animations in percentages, just like this:
@keyframes myanimation {0%{opacity:0; Transform:translate (0,0); } -%{opacity:1; Transform:translate (0,0); } -%{transform:translate (100px,0); } -%{transform:translate (100px, 100px); }} #box {animation:myanimation2. 75s;}
But when it comes to animations, don't you think it's better to use the time representation than percent? It's like "1 seconds to reduce transparency, then 0.75 seconds to the right, then 1 seconds to drop". If you have spent a few hours on a percentage-time basis, will the customer ask you to increase the intermediate step by 3 seconds? You need to recalculate all the percentages!
Many experiments are often required to create animations, especially for time and ease, which is seek()
where the approach can be useful. Imagine that you created a 60-second-length animation and then needed to process the last 5 seconds, in order to see the effect of the edits, you have to wait for 55 seconds each time before the line. You can use this method to skip the previous time and finally remove the method, which can save a lot of time.
More and more scenes are now created for animating canvas-based objects and third-party library objects, and CSS animations can only target DOM elements. This means that even if you spend a lot of time researching CSS animations, it won't be useful in a project like that, and you'll have to change the tools at the end.
The following are some of the conveniences that some other CSS animations cannot provide for workflow-related:
- Relative value. For example, "rotate 30 degrees" or "move the elements from the beginning of the animation down to 100 pixels."
- Nested. Imagine nesting an animation in another animation that can also be nested, and so on. Imagine controlling the active painting when all the animations can be synchronized. Such structures can facilitate the generation of modular code, which facilitates production and maintenance.
- Process reports. Did the specific animation end? If not, where is it now in the process?
- Specific deletions. Sometimes it is useful to only remove all animations on one element that affect their size (or any property you think of) while allowing other animations to take place.
- The code is concise. The code for CSS keyframes animations can be lengthy even if you don't add extra-prefixed attributes. Anyone who wants to implement a slightly more complex animation with CSS can attest that the CSS code will eventually become unwieldy. In fact, the size of the CSS code that implements the animation may be larger than the size of the JavaScript library (it can be cached and reused in many animations).
Limited effect
None of the following effects can be implemented with CSS:
- To move along a curve (such as a Bezier curve)
- Use interesting easing effects, such as elastic, bouncing, or rough effects. Although
cubic-bezier()
this option is available, it allows only two control points, so the functionality is also very limited.
- Use different easing effects for different properties in CSS keyframes animations. The ease is applied to the entire CSS keyframes.
- Physics-based actions. For example, a flicker with impact effect, or a recovery state, as in this demo.
- The animation of the scrolling position.
- Specifies the rotation of the direction. For example, rotate 270 degrees in the shortest direction, or clockwise and counterclockwise.
- Animation of element properties
Compatibility
CSS-based animations are not available in IE9 and in previous versions of the browser, and most of us hate adapting to older browsers, especially IE, but the reality is that some of our customers will require that support.
Prefixes are required for many browsers, but you can use precompiled tools to avoid writing them manually.
Conclusion
CSS animation is not good, of course not. In fact, it is very convenient to implement some simple state transformations (such as flipping) that do not require CSS animations to be compatible with older browsers. 3D transformations can often perform very well (IOS7 is an exception). CSS animations are very appealing to developers who like to put all of the animation implementations on the CSS layer. However, JavaScript-based animations are more flexible and can better implement complex animations and lots of interactivity. And unlike what you've heard, it can have the same or even better performance as CSS animations.
When jQuery.animate()
I compare it, I can understand why CSS animations are so popular. Who doesn't want 10 times times the performance boost? But soon there is no choice between jQuery and CSS, and the JavaScript-based tool GSAP offers new possibilities and eliminates performance gaps.
This article is not about GSAP or any other library; it's about JavaScript animations that shouldn't have a bad reputation. In fact, JavaScript is the only option to build a robust, flexible animation system. Also, I want you to see the disappointing parts of CSS animations so that you can make more scientific choices about how animations are implemented.
Does the Web Animation standard solve the problem?
The consortium is working on a new standard for solving the drawbacks of CSS animations and transformations, providing better control and more functionality. It does make a lot of progress in many ways, but it is also flawed (some of them are even impossible, and they conflict with existing legitimate CSS standards, for example, independent transformation control components seem impossible). But that's another topic, and we can see how things go. After all, there are a lot of smart people who are trying to work on this standard.
CSS vs. JavaScript for animating