CSS vs JS animations: who is faster?

大家讲道理
Release: 2016-11-10 11:53:14
Original
1069 people have browsed it

This article is translated from CSS vs. JS Animation: Which is Faster? by Julian Shapiro. Julian Shapiro is also the creator of Velocity.js. This is a very efficient, simple and easy-to-use JS animation library. He has high attainments in Web animation.

                                                                                                                                                                                                                                                                                       industries What is the secret? How do Adobe and Google make their media-rich mobile sites as fast as native apps? CSS vs JS animations: who is faster?

This article will tell you step by step why Javascript-based DOM animation libraries (such as Velocity.js and GSAP) can be more efficient than jQuery and CSS-based animation libraries.

 jQuery

  Let’s start with the basics: Javascript and jQuery cannot be confused. Javascript animations are fast, while jQuery animations are slow. why? Because although jQuery is extremely powerful, its design goal is not to be an efficient animation engine:

jQuery cannot avoid layout thrashing (some people like to translate it as "layout thrashing", which will lead to redundant relayout/reflow), because it The code is not only used for animation, it is also used in many other scenarios.
  • jQuery consumes a lot of memory and often triggers garbage collection. It is easy for the animation to get stuck when garbage collection is triggered.
  • jQuery uses setInterval instead of reqeustAnimationFrame(RAF), because RAF will stop firing when the window loses focus, which will cause jQuery bugs. (Currently jQuery already uses RAF)
  • Note that layout thrashing will cause the animation to freeze at the beginning, and the triggering of garbage collection will cause the animation to freeze during running. Not using RAF will cause the animation frame rate to be low.
Implementation example

In order to avoid layout thrashing, we need to access and update the DOM in batches.

var currentTop,
    currentLeft;
/* 有 layout thrashing. */
currentTop = element.style.top; /* 访问 */
element.style.top = currentTop + 1; /* 更新 */
currentLeft = element.style.left; /* 访问 */
element.style.left = currentLeft + 1; /* 更新 */
/* 没有 layout thrashing. */
currentTop = element.style.top; /* 访问 */
currentLeft = element.style.left; /* 访问 */
element.style.top = currentTop + 1; /* 更新 */
element.style.left = currentLeft + 1; /* 更新 */
Copy after login

  Access operations after an update operation will force the browser to recalculate the style of the page element (because the updated style must be applied to obtain the correct value). This does not cause much performance loss in normal operation, but it will cause significant performance overhead when placed in animations with an interval of only 16ms. Just slightly changing the order of operations can greatly improve animation performance.

Similarly, using RAF won’t let you refactor your code a lot. Let’s compare the difference between using RAF and using setInterval:

var startingTop = 0;
/* setInterval: Runs every 16ms to achieve 60fps (1000ms/60 ~= 16ms). */
setInterval(function() {
    /* Since this ticks 60 times a second, we divide the top property's increment of 1 unit per 1 second by 60. */
    element.style.top = (startingTop += 1/60);
}, 16);
/* requestAnimationFrame: Attempts to run at 60fps based on whether the browser is in an optimal state. */
function tick () {
    element.style.top = (startingTop += 1/60);
}
window.requestAnimationFrame(tick);
Copy after login

You only need to slightly modify the code to use RAF, and your animation performance will be greatly improved.

CSS Transition

 The animation logic of CSS transition is executed by the browser, so its performance can be better than jQuery animation. Its advantages are reflected in:

Reduce lag by optimizing DOM operations and avoiding memory consumption
  • Using a mechanism similar to RAF
  • Forcing the use of hardware acceleration (improving animation performance through GPU)
However, Javascript can actually use these optimizations as well. GSAP has been doing these optimizations for a long time. Velocity.js is an emerging animation engine that not only does these optimizations, but even goes further. We'll talk about these later.

Facing the facts, making Javascript animations comparable to the performance of CSS animations is just the first step in our great plan. The second step is the most important step, making Javascript animation faster than CSS animation!

 Let’s take a look at the flaws of the CSS animation library:

Transition forces the use of the GPU hardware acceleration. As a result, the browser is always running under high load, which will cause the animation to become stuck. This is even more severe on mobile browsers. (It should be noted that when data is frequently transmitted between the browser's main thread and the synthesis thread, performance is particularly consumed, so it is easy to cause lagging. Some CSS properties are not affected. Adobe's blog talks about this.
  • Browsers below IE 10 do not support transition. Currently, IE8 and IE9 are still very popular.
  • transition cannot be completely controlled by Javascript (transition can only be triggered by Javascript), because the browser does not know how to let Javascript control the animation and optimize the performance of the animation at the same time.
  •   On the other hand: Based on Javascript, you can decide when to enable hardware acceleration, it can support all versions of IE, and it can fully optimize batch animations.
  • 我的建议是:当你只在移动平台上开发,并且动画只是简单的状态切换,那么适合用纯 CSS transition。在这种情况下,transition 
    是高性能的原生支持方案。它可以让你将动画逻辑放在样式文件里面,而不会让你的页面充斥 Javascript 
    库。然而如果你在设计很复杂的富客户端界面或者在开发一个有着复杂UI状态的 
    app。那么我推荐你使用一个动画库,这样你的动画可以保持高效,并且你的工作流也更可控。有一个特别的库做的特别棒,它可以用 Javascript 
    控制 CSS transition。这就是 Transit。
    Copy after login

  • Javascript animation

  所以 Javascript 可以比 CSS transition 性能更好。但是它到底有多块呢?它快到足够可以构建一个3D 动画的demo,通常需要用到 WebGL 才能完成。并且它快到足够搭建一个多媒体小动画,通常需要 Flash 或者 After Effects 才能完成。并且它还快到可以构建一个虚拟世界,通常需要 canvas 才能完成。

  为了更直接的来比较主流动画库的性能,包括 Transit(使用了 CSS transition),让我们打开Velocity的官方文档。

  之前那个问题还在:Javascript 是如何达到高性能的呢?下面是一个列表,列举了基于 Javascript 的动画库能做的事情:

  • 同步DOM -> 在整个动画链中微调堆栈以达到最小的layout thrashing。

  • 缓存链式操作中的属性值,这样可以最小化DOM的查询操作(这就是高性能 DOM 动画的阿喀琉斯之踵)

  • 在同一个跨同层元素的调用中缓存单位转化比率(例如px转换成%、em等等单位)

  • 忽略那些变动小到根本看不出来的DOM更新

  让我们重新温习下之前学到的关于layout thrashing的知识点。Velocity.js 运用了这些最佳实践,缓存了动画结束时的属性值,在紧接的下一次动画开始时使用。这样可以避免重新查询动画的起始属性值。

$element
    /* Slide the element down into view. */
    .velocity({ opacity: 1, top: "50%" })
    /* After a delay of 1000ms, slide the element out of view. */
    .velocity({ opacity: 0, top: "-50%" }, { delay: 1000 });
Copy after login

  在上面的样例中,第二次调用 Velocity 时已经知道了 opacity 的起始值为 1,top 的值为 50%。

  浏览器也可以使用与此类似的优化,但是要做这些事情太过激进,使用场景也会受到限制,开发者就有可能会写出有bug的动画代码。jQuery就是因为这个原因没有使用RAF(如上所说),浏览器永远不会强行实施可能打破规范或者可能偏离期望行为的优化。

  最后,让我们来比较下两个Javascript框架(velocity.js 和 GSAP)。

  • GASP 是一个快速且功能丰富的动画平台。Velocity则更为轻量级,它大大地改善了UI动画性能和工作流程。

  • GSAP 需要付费才能用于商业产品。Velocity 是完全免费的,它使用了自由度极高的 MIT 协议。

  • 性能方面,两者几乎相当,很难区分胜负。

我个人推荐在你需要如下功能时使用 GSAP:精确控制时间(例如 remapping,暂停/继续/跳过),或者需要动作(例如:贝赛尔曲线路径),又或者复杂的动画组合/队列。这些特性对游戏开发或者复杂的应用很重要,但是对普通的 web app 的 UI 不太需要。

 Velocity.js

  之前提到了 GSAP 有着丰富的功能,但这不代表 Velocity 的功能简单。相反的,Velocity 在 zip 压缩之后只有 7kb,它不仅仅实现了 jQuery animate 方法的所有功能,还包含了 颜色、transforms、loop、easings、class 动画和滚动动画等功能。

  简单的说就是 Velocity 包含了 jQuery、 jQuery UI 和 CSS transition 的功能。

  更进一步从易用性的角度来讲,Velocity 使用了 jQuery 的$.queue() 方法,因此可以无缝过渡到 jQuery 的$.animate()、$.fade()和$.delay()方法。并且 Velocity 的语法和$.animate()一摸一样,所以我们根本不需要修改页面的现有代码。

  让我们快速过一下 Velocity.js 的例子:

$element
    .delay(1000)
    /* Use Velocity to animate the element's top property over a duration of 2000ms. */
    .velocity({ top: "50%" }, 2000)
    /* Use a standard jQuery method to fade the element out once Velocity is done animating top. */
    .fadeOut(1000);
Copy after login

  如下是一个高级用法:滚动网页到当前元素并且旋转元素。这样的动画只需要简单的几行代码:

$element
    /* Scroll the browser to the top of this element over a duration of 1000ms. */
    .velocity("scroll", 1000)
    /* Then rotate the element around its Y axis by 360 degrees. */
    .velocity({ rotateY: "360deg" }, 1000);
Copy after login

 总结

  Velocity 的目标是成为 DOM 动画领域性能最好易用性最高的库。这篇文章主要关注了性能方面。易用性方面可以前往 VelocityJS.org 了解。

  在结束之前,请记住一个高性能的 UI 绝不仅仅是选择一个正确的动画库。页面上的其他代码也需要优化。可以看看Google那些非常棒的演讲:

Jank Free

Rendering Without Lumps

Faster Websites


source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!