CSS vs. JS Animation: 哪个更快?

CSS vs. JS Animation: 哪个更快?

基于JavaScript的动画竟然已经默默地比CSS的transition动画快了?而且,Adobe和
Google竟然直接在昭示可以媲美原生应用的富媒体移动站点?

这篇著作将会逐点讲解基于JavaScript的DOM动画库,比如Velocity.js和GSAP,是怎样比jQuery和按照CSS的动画库高效的。

jQuery

让我们先从这个谜底开端:JavaScript和jQuery被张冠李戴的混淆了。JavaScript的动画片是快的,可是jQuery的卡通慢。为啥?因为即使jQuery很有力,不过它的靶子没有是为了变成一个急忙的卡通片引擎。

  • jQuery不能避免布局震荡因为它的代码除了动画还提供了很多效果。

  • jQuery的内存消耗日常接触垃圾回收,导致卡通卡住

  • jQuery使用setInterval而不是requestAnimationFrame
    (RAF)为了避免有些bug

注意,布局震荡引起了动画开始处的卡顿,垃圾回收导致了动画进行中的卡顿,RAF的缺席导致了帧率低。

落实的例子

制止布局震荡,包括简单地集合DOM查询和DOM更新:

var currentTop,
  currentLeft;

/* 有布局震荡 */
currentTop = element.style.top; /* QUERY */
element.style.top = currentTop + 1; /* UPDATE */

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

/* 没有布局震荡 */
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: 每16ms运行一次来达到60fps (1000ms/60 ~= 16ms). */
setInterval(function() {
  /* 由于这里的代码会在1s内执行60次,所以我们把top属性每秒1单位的增长分成60份 */
    element.style.top = (startingTop += 1/60);
}, 16);

/* requestAnimationFrame: 不管浏览器是否处于最优状态,都试图运行在60fps */
function tick () {
    element.style.top = (startingTop += 1/60);
}

window.requestAnimationFrame(tick);

RAF极大限度地加强了动画片的特性。而你只需要修改为数不多的代码。

CSS Transitions

CSS
transitions的卡通性能优于jQuery,它把动画的逻辑交给了浏览器本身。这会推向:1)优化DOM交互和内存消耗以避免卡顿,2)在底部借助RAF的性状,3)强制硬件加速(借助GPU的力量来增强动画性能)。

但是,实际处境是,这一个优化可以一贯通过JavaScript来促成,GSAP现已致力于此多年。Velocity.js,一个新的卡通引擎,不止借助于上述技术,还动用了其它格局–我们将快捷探讨。

领会JavaScript动画可以媲美CSS动画库这一真相,只是我们计划的率先步。第二步是咱们要精通JavaScript动画可以比CSS动画还快。

让我们从检查CSS动画库的短处起始:

  • Transitions的胁制硬件加速是使GPU加速,但是那反而会促成GPU强压情形下动画的卡顿。那么些潜移默化在移动装备上更为严重。(特别地,这么些卡顿是由于数量在浏览器的主线程和排序线程间传递的开销导致的。一些CSS属性,比如transforms和opacity,是不受这一个开销影响的。)Adobe在这里解说了那多少个题目。

  • Transitions在IE10之下有包容问题,
    这在PC端站点会很容易导致问题发出,因为IE8和IE9仍然很流行

  • 因为transitions并不是被JavaScript控制(它们只是被JavaScript触发),浏览器并不知道怎么着共同地运用JavaScript代码来操控优化transitions。

反而地:基于JavaScript的动画片库,能够友善控制哪些时候利用硬件加速,可以兼容所有版本的IE,并且它们分外适合批量动画片优化。

自家的提出是,当你只是开发活动站点,并且您的动画片只包含简单的动静变化时,可以行使原生CSS
transitions。在这种场所下,transitions算是一种高效并且原生的缓解方案,并且能够把装有的卡通片逻辑只放在css中,避免了因为引入JavaScript库而招致页面臃肿。可是,假若你正在规划复杂的UI,或者正在开发具有状态UI的应用程序,请使用JavaScript动画库,它可以使你的动画片保持高性能,使您的办事流程保持可控。特别是在管理CSStransitions方面做得很棒的一个库是

Transit

JavaScript Animation

Okay,所以JavaScript在性能上得以占上风。可是JavaScript究竟可以快多少吗?其实,它曾经快到可以创建复杂的,平日只能用WebGL构建的3D
animation
demo
。已经快到可以创建平时只可以用Flash或者影效处理完成的multimedia
teaser
。已经快到可以成立通常只可以用canvas构建的virtual
world

为了直观相比较动画库的超过性能,包括Transit(内部使用CSS
transitions),请查阅Velocity的文档,在VelocityJS.org

反之亦然存在问题:JavaScript究竟咋样达到高性能?下边是基于JavaScript的卡通库能实现的优化列表:

  • 为了减弱布局震荡,将总体动画中关系到DOM同步化到库房中。

  • 缓存链式调用中的属性值,以尽量收缩DOM查询(它是熏陶DOM动画性能的沉重缺点)的产生。

  • 在同一个跨同级元素调用中缓存单位转换比率(例如PX到%、em等)。

  • 当样式更新在视觉上不显然时,跳过更新。

回首从前讲的布局震荡,Velocity.js利用那个顶级实践来缓存动画的结束值,那一个值会被录用为今后动画的始发值,从而防止再度查询DOM元素的起头值:

$element
  /* 将元素向下滑动到视图中。 */
  .velocity({ opacity: 1, top: "50%" })
  /* 延迟1000ms,元素滑动出视图 */
  .velocity({ opacity: 0, top: "-50%" }, { delay: 1000 });

在地点的例证中,第二个Velocity自动知道它应该从opacity为1,top为50%起始。

浏览器最终得以友善履行很多一律的优化,但如此做将索要庞大地范围开发人员编写动画代码的措施。由此,同样的来由,jQuery不采用RAF(见上文),浏览器也永远不会强加优化,尽管这个优化只有可怜小的或是会打破专业或离开预期的行为。

最终,让我们来相比一下那六个JavaScript动画库(Velocity.js和GSAP)。

  • GSAP是一种高效、功用充分的动画片平台。Velocit是一个轻量级工具,可以极大地提高UI动画性能和工作流程。

  • GSAP需要许可费。Velocity是由此许MIT开源的。

  • 属性都很不错,GSAP和Velocity在真正项目中一直不区分。

本身的提出是:当您需要规范的决定(例如重映,暂停/復苏/搜索)、运动(例如Bezier曲线路径),或复杂的分组/排序时,使用GSAP。这一个特色对于游戏开发和某些niche应用非凡首要,但在Web应用程序的UI中并不普遍。

Velocity.js

稳定GSAP效率丰硕,并不表示Velocity效能单一。相反地,在收缩后只有7Kb的文本中,Velocity不仅提供了jQuery$.animate()的有着机能,而且提供了color
animation,transforms,loops,easings,class animation和scrolling。

粗略,Velocity是jQuery、jQuery UI和CSStransitions的特级结合。

愈来愈,从福利的角度,Velocity在底层使用jQuery的$.queue()办法,由此得以无缝地与jQuery的$.animate(),
$.fade()$.delay()函数交互。并且,由于Velocity的语法和$.animate()一致,您页面的代码不需要修改

让我们很快看一下Velocity.js。在基础动画上,Velocity和$.animate()一样:

$element
  .delay(1000)
  /* 使用Velocity的2000ms内改变元素top属性的动画*/
  .velocity({ top: "50%" }, 2000)
  /* 当上面Velocity动画执行完时,使用标准的jQuery方法来使元素淡出*/
  .fadeOut(1000);

在高级动画上,复杂的滚动场景和三维动画都得以创设——只需要两行简单的代码:

$element
  /* 在1000ms内,浏览器滚动到这个元素的顶部 */
  .velocity("scroll", 1000)
  /* 之后使元素绕着它的Y轴旋转360度。 */
  .velocity({ rotateY: "360deg" }, 1000);

结束语

Velocity的目标是保持超越的DOM动画性能和便当。本文的关键是前者。请去VelocityJS.org上学更多关于后世的文化。

在咱们截至在此以前,记得_*一个高性能的UI不仅仅是选项适宜的动画库_。页面的其它部分也应当优化。从底下这多少个奇妙的Google话题中学习更多:

相关文章

网站地图xml地图