CSS VS JS动画,哪个更快[译]

英文原文:https://davidwalsh.name/css-js-animation

原作者Julian Shapiro是Velocity.js的作者,Velocity.js是一个高效易用的js动画库。在《Javascript网页动画设计》一书中对这个库有很多更具体的剖析,对Velocity及JS动画感兴趣的可以一看。

基于Javascript的动画怎么可能总是和 CSS transition 一样快,甚至更快呢?到底是什么秘密呢?Adobe 和 Google 是怎么做到让他们的富媒体移动网站的速度和 native app 媲美的?

这篇文章会一点点告诉你为什么基于 Javascript 的 DOM 动画库(比如 Velocity.js 和 GSAP)能够比 jQuery 和基于 CSS 的动画库更高效。

JQuery

让我们从最基础的开始说起: Javascript 和 jQuery 两者不能错误的混为一谈。Javascript 动画很快,而 jQuery 动画却慢下来。为什么呢?因为尽管 jQuery 非常强大,但是它的设计目标并不是一个高效的动画引擎:

1.JQuery不能避免layout thrashing,由于它不仅仅要服务于动画,也需要用于其他场景。

2.JQuery的内存消耗会频繁的触发垃圾回收机制,而垃圾回收会让动画暂时卡住。

3.JQuery使用了setInterval而不是requestAnimationFrame(RAF),为了避免RAF在失去焦点的时候停止动画(译者注:JQuery3.0集成了RAF,不支持IE8及以下版本了)。

注意 layout thrashing 是导致动画在开始的时候卡顿的原因,垃圾回收是导致动画运行过程中的卡顿的原因,不使用 RAF 通常会导致动画帧率低。

实现样例

避免layout thrashing,由批量同步操作DOM请求和DOM更新组成。

var currentTop,
    currentLeft;

/* With layout thrashing. */
currentTop = element.style.top; /* QUERY */
element.style.top = currentTop + 1; /* UPDATE */

currentLeft = element.style.left; /* QUERY */
element.style.left = currentLeft + 1; /* UPDATE */

/* Without layout thrashing. */
currentTop = element.style.top; /* QUERY */
currentLeft = element.style.left; /* QUERY */

element.style.top = currentTop + 1; /* UPDATE */
element.style.left = currentLeft + 1; /* UPDATE */

在更新操作之后的访问操作会强制浏览器重新计算页面元素的样式(因为要将更新的样式应用上去才能获取正确的值)。这个在一般操作下没太大的性能损失,但是放在间隔仅仅16ms的动画中则会导致显著的性能开销。只需要稍微改动下操作的顺序就可以大大提高动画的性能。

类似地,使用 RAF 也不会迫使你大量重构现在的代码。让我们来比较下使用 RAF 和使用 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);

RAF可以提供对动画性能最大可能的提升,而为此你只需要对你的代码进行一个简单的修改。

CSS Transitions

CSS transition的性能能够比 jQuery 动画好,transition将动画逻辑抛给浏览器自身来执行。它的优势体现在:

1.通过优化 DOM 操作和内存消耗来避免卡顿

2.利用RAF底层的原理

3.强制硬件加速(使用GPU加速来提高动画效果)。

然而实际上Javascript可以直接使用这些优化。GSAP 已经做这些优化有些年头了。Velocity.js ,一个新的动画引擎,不仅仅实现了相同的技术,而且走的更远些。稍后会谈到这些。

面对现实,让 Javascript 动画可以与 CSS 动画性能竞争只是我们复兴计划的第一步。第二步是意识到事实上 Javascript 动画比 CSS 动画快!

让我们以测试CSS动画的缺陷开始吧:

1.Transition的强制使用GPU加速,致使动画卡顿不流畅和高负荷下的束缚。这种情况在移动设备上会加剧发生。(特别需要说明的是,卡顿是由于当数据在浏览器的主线程和其排序线程之间传输的时候发生的过载引起的。一些CSS属性,例如transforms和opacity,不会受到这种限制。)Adobe兄弟的博客谈论过这个话题。

2.Transition在IE10不会起作用,这使得很多桌面场景残留的IE8、IE9中会产生兼容问题。

3.由于Transition不能原生地被javascript控制(仅仅是被javascript触发),浏览器不知道如何去优化操作Transition的javascript代码。

相反的,基于javascript的动画库可以自己决定什么时候启用硬件加速,他们很自然的在IE各版本下正常工作,而且他们也非常适合批量动画优化。

我的建议是可以在专门为移动端开发的页面上使用原生的css Transitions,并且你的动画只由简单的状态变化组成。在这样的情况下,transitions是一个允许你把动画的逻辑全部保留在css样式表里面,不会因为使用太多javascript库导致页面膨胀的 高性能内嵌的方法。但是,你如果正在设计复杂的UI动画或者正开发一款多状态UI的APP,记得用动画库,以便你的动画处于高性能状态,你的工作流程处于易处理状态。

JavaScript动画

好,javascript在使用的时候性能是可以占优势的。但javascript究竟可以快多少?开始--快到足以建立一个对比强烈的3D演示动画,就像你想的那样,通常用webGl才能完成的。快到足以建立一个复杂的多媒体动画,通常使用Flash或After Effects才能完成的。

快到可以构建一个虚拟世界,通常使用canvas才能完成的。

为了直接比较主流的动画库的表现,包括Transit(它使用了CSS的Transition),可以在这里先看看Velocity的官方文档:VelocityJS.org

之前的问题还在:javascript如何达到高性能的?

下面列出了一些优化,javascript的动画库可以胜任的表现:

1.同步DOM-》调整堆栈之间的动画链来最小化布局抖动。

2.在链式调用中缓存属性值来最小化DOM查询的发生(这就是高性能动画的阿喀琉斯之踵)。

3.当更新基本上看不出来时,跳过样式更新。

可以重温下我们之前讨论过的布局抖动,velocity.js利用这些最佳实践,来缓存动画结束值,使其被重用为随后的动画的起始值。以此来避免再次查询DOM元素的起始值。

    $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 });

在上面的例子中,第二次velocity调用时已经知道,应该在opacity为1,top为50%时自动开始。

浏览器可以自身执行类似这样的优化,但是这样做会很大程度上限制开发者手工写动画代码的方法。

因此,基于同样的原因,Jquery不用RAF(见上文),浏览器从不实行 可能会打破规范或者偏离预期行为的优化。

最后,让我们来比较一下两个javascript动画库(velocity和GSAP)。

1.GSAP是一个快速,功能丰富的动画库平台。velocity是一个大大提高UI动画性能和工作刘的轻量级的工具。

2.GSAP对于种类繁多的商业应用需要付费,velocity是完全开源免费的,它使用了十分自由的MITlicence。

3.在实际应用中,两者的性能表现相当。

我的建议是你需要精确控制时间的时候使用GSAP(例如:remapping,暂停\继续\跳过),移动(例如贝塞尔曲线),或者复杂的动画组合\队列。这些特性对于游戏开发及一些特殊应用十分重要,但在web应用中不太常见。

Velocity.js

GSAP有着富特性功能,但不意味着Velocity自身功能不丰富。相反,在压缩之后7KB的包里面,Velocity不仅仅实现了Jqueryanimate的所有功能,也打包了色彩动画,变换,循环,移动,类动画,滚动。

简而言之,Velocity是了jQuery, jQuery UI, 和CSS transitions的最棒结合。

更进一步,从方便的角度来说,V在底层用了Jquery的$.quene()方法。所以和Jquery的$.animate(), $.fade(), and $.delay()是无缝互操作的。此外,由于V的语法和$.animate()是完全一致的,页面的代码都不需要改。

让我们快速看下V。V和animate的语法完全一样:

$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);

高级用法里面,复杂的滚动场景与3D动画可以创建-只有2行简单的代码:

$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);

总结

V的目标是成为在DOM动画性能和方便的领导者。这篇文章的重点是前者。最前面提到的velocityjs.org可以了解后者。

在我们结束之前,请记住,一个高性能的UI不仅仅是选择合适的动画库。页面的其余部分也应该进行优化。

时间: 2024-10-13 10:07:31

CSS VS JS动画,哪个更快[译]的相关文章

CSS 和 JS 动画哪个更快

基于Javascript的动画暗中同CSS过渡效果一样,甚至更加快,这怎么可能呢?而Adobe和Google持续发布的富媒体移动网站的性能可媲美本地应用,这又怎么可能呢? 本文逐一遍览了基于Javascript的DOM动画库,如Velocity.js和GSAP,看其是如何比jQuery和CSS动画效果更具性能的. jQuery 让我们先从基础的开始: JavaScript 和 jQuery 被错误的混为一谈了. JavaScript 动画是很快的. jQuery 把它放慢了下来.为什么?因为 —

CSS vs. JS Animation: 哪个更快

CSS vs. JS Animation: 哪个更快? CSS vs. JS Animation: 哪个更快? 基于JavaScript的动画竟然已经默默地比CSS的transition动画快了?而且,Adobe和 Google竟然一直在发布可以媲美原生应用的富媒体移动站点? 这篇文章将会逐点讲解基于JavaScript的DOM动画库,比如Velocity.js和GSAP,是如何比jQuery和基于CSS的动画库高效的. jQuery 让我们先从这个事实开始:JavaScript和jQuery被

CSS vs JS动画:谁更快?

CSS vs JS动画:谁更快? 2016-05-16 前端大全 (点击上方公众号,可快速关注) 英文:Julian Shapiro 译者:MZhou's blog 链接:http://zencode.in/19.CSS-vs-JS动画:谁更快?.html 这篇文章翻译自 Julian Shapiro 的 CSS vs. JS Animation: Which is Faster?.Julian Shapiro 也是 Velocity.js 的创造者.这是一个非常高效.简单易用的JS动画库.他在

JQuery动画插件Velocity.js发布:更快的动画切换速度

5月3日,Julian在其GitHub上发布了Velocity.js.Velocity.js是一款动画切换的jQuery插件,它重新实现了jQuery的$.animate()方法从而加快动画切换的速度.Velocity.js只有7k的大小,它不仅包含了$.animate()的所有功能,并且还包含了颜色切换.转换(transform).循环.缓动.CSS切换.Scroll功能,它是jQuery. jQuery UI.CSS变换 在动画方面的最佳组合.Velocity.js支持IE8+.Chrome

How Javascript works (Javascript工作原理) (十三) CSS 和 JS 动画底层原理及如何优化其性能

个人总结:读完这篇文章需要20分钟. 这是 JavaScript 工作原理的第十三章. 概述 正如你所知,动画在创建令人叹服的网络应用中扮演着一个关键角色.由于用户越来越注重用户体验,商户开始意识到完美,令人愉悦的用户体验的重要性,结果网络应用变得越来越重并且拥有更多动态交互的功能.这就要求网络应用提供更加复杂的动画来实现平滑的状态过渡贯穿于用户的使用过程当中.现在,这已经司空见惯.用户变得越来越挑剔,他们潜意识期许可以获得快速响应和良好交互的用户界面. 然而,让界面具有动画效果不一定是件简单的

CSS VS JS动画,哪个更快

JQuery 让我们从最基础的开始说起: Javascript 和 jQuery 两者不能错误的混为一谈.Javascript 动画很快,而 jQuery 动画却慢下来.为什么呢?因为尽管 jQuery 非常强大,但是它的设计目标并不是一个高效的动画引擎: 1.JQuery不能避免layout thrashing,由于它不仅仅要服务于动画,也需要用于其他场景. 2.JQuery的内存消耗会频繁的触发垃圾回收机制,而垃圾回收会让动画暂时卡住. 3.JQuery使用了setInterval而不是re

自从用了Less 编写css,你比以前更快了~(sublime编译)

之所以用这个标题呢,主要是最近调侃杰伦太有意思了. 好吧,开个玩笑而已. 如果你了解过Less,并对之很熟悉,就不用往下看了. 如果你没用过,恭喜,这是一个入门级的教程,学会了它,可以为你节省10%的绳命. 首先,我们得知道Less能干什么.如: @width:300px; @fonts:12px bold "宋体,Verdana"; .block-header{ color:#5c5c5c; .elem-title{ font:@fonts; width:@width; } .ele

更轻更快的Vue.js 2.0与其他框架对比(转)

更轻更快的Vue.js 2.0 崭露头角的JavaScript框架Vue.js 2.0版本已经发布,在狂热的JavaScript世界里带来了让人耳目一新的变化. Vue创建者尤雨溪称,Vue 2.0 在性能上有显著的提升,同时保持轻量的文件下载: 渲染层基于一个轻量级的Virtual DOM实现进行了重写,该Virtual DOM实现fork自snabbdom.新的渲染层相比v1带来了巨大的性能提升,也让Vue 2.0成为了最快速的框架之一. 根据1.0到2.0迁移指南,“大约90%的API是相

JS动画与CSS动画

一.JS动画(setInterval setTimeOut requestAnimationFrame) 优点: 1)过程控制能力强.可以对动画工程进行精准的控制,暂停.取消.开始.终止都可以. 2)动画效果多.炫酷.有一些效果是CSS动画所不能实现的 3)兼容性比较高 缺点: 1)由于JS是通过不断的操作DOM和CSS的属性来实现动画效果的,这需要不断的重排(reflow)和重绘(repaint),非常消耗浏览器的内存.(在PC端有浏览 器可以分配的内存比较大,动画的重排(reflow)和重绘