CSS vs. JS Animation: 哪个更快?

CSS vs. JS Animation: 哪个更快?

基于JavaScript的卡通片竟然一度默默地比CSS的transition动画快了?而且,Adobe和
谷歌竟然直接在颁发可以比美原生应用的富媒体移动站点?

这篇文章将会逐点讲解基于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地图