CSS3动画 相比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 + ; /* UPDATE */ currentLeft = element.style.left; /* QUERY */
element.style.left = currentLeft + ; /* UPDATE */ /* 没有布局震荡 */
currentTop = element.style.top; /* QUERY */
currentLeft = element.style.left; /* QUERY */ element.style.top = currentTop + ; /* UPDATE */
element.style.left = currentLeft + ; /* UPDATE */
发生在更新之后的查询会强制浏览器立马重新布局,并计算给出页面样式的计算值(把更新的影响考虑在内)。这对于运行于16ms间隔的动画来讲,会产生巨大的开销。
同样,实现RAF并不需要对既有代码改动很大。让我们来对比一下RAF的实现和setInterval的实现:
var startingTop = ; /* setInterval: 每16ms运行一次来达到60fps (1000ms/60 ~= 16ms). */
setInterval(function() {
/* 由于这里的代码会在1s内执行60次,所以我们把top属性每秒1单位的增长分成60份 */
element.style.top = (startingTop += /);
}, ); /* requestAnimationFrame: 不管浏览器是否处于最优状态,都试图运行在60fps */
function tick () {
element.style.top = (startingTop += /);
} 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: , top: "50%" })
/* 延迟1000ms,元素滑动出视图 */
.velocity({ opacity: , top: "-50%" }, { delay: });
在上面的例子中,第二个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()
/* 使用Velocity的2000ms内改变元素top属性的动画*/
.velocity({ top: "50%" }, )
/* 当上面Velocity动画执行完时,使用标准的jQuery方法来使元素淡出*/
.fadeOut();
办公资源网址导航 https://www.wode007.com
在高级动画上,复杂的滚动场景和三维动画都可以创建——只需要两行简单的代码:
$element
/* 在1000ms内,浏览器滚动到这个元素的顶部 */
.velocity("scroll", )
/* 之后使元素绕着它的Y轴旋转360度。 */
.velocity({ rotateY: "360deg" }, );
结束语
Velocity的目标是保持领先的DOM动画性能和便捷。本文的重点是前者。请去VelocityJS.org学习更多关于后者的知识。
在我们结束之前,记得*一个高性能的UI不仅仅是选择合适的动画库。页面的其余部分也应该优化。从下面这些奇妙的Google话题中学习更多:
CSS3动画 相比JS Animation 哪个更快?的更多相关文章
- CSS vs. JS Animation: 哪个更快
CSS vs. JS Animation: 哪个更快? CSS vs. JS Animation: 哪个更快? 基于JavaScript的动画竟然已经默默地比CSS的transition动画快了?而且 ...
- css3 动画 vs js 动画
之前被问到过,css3 动画与 js 动画孰优孰劣,脑袋的第一反应就是性能上肯定 css3 动画会好很多,但别人说不对,我就在想,不对?难道还有别的原因吗?答案是肯定的.先来看看二者实现动画的原理吧. ...
- CSS3动画和JS动画的比较
前言 之前有被问到一个问题,css3动画和js动画性能谁更好,为什么.据我的经验,当然觉得css3动画性能更好,至于为什么一时还真答不上来,所以特意查了一下资料总结一波. JS动画 优点: js动画控 ...
- 使用jquery封装的动画脚本(无动画、css3动画、js动画)
自己封装好的showhide.js 包含无动画.css3动画.js动画 包括:fade(淡入淡出) slideUpDown(上下滑动) slideLeftRight(左右滑动) fadeSlid ...
- css3动画与js动画的一些理解
http://zencode.in/19.CSS-vs-JS%E5%8A%A8%E7%94%BB%EF%BC%9A%E8%B0%81%E6%9B%B4%E5%BF%AB%EF%BC%9F.html 首 ...
- CSS3动画效果——js调用css动画属性并回调处理详解
http://www.jb51.net/css/258407.html 这篇文章主要详细介绍了CSS3动画效果回调处理,需要的朋友可以参考下 我们在做js动画的时候,很多时候都需要做回调处理,如在一个 ...
- CSS3动画与JS动画的优缺点?
JS动画: 缺点:1.JS在浏览器的主线程中运行,而主线程还有其他的js脚本,样式布局,绘制任务等,对其干扰可能导致线程出现阻塞,从而造成丢帧的情况. 2.JS动画代码复杂度高于CSS3动画. 优点: ...
- css3动画与js动画的区别
css与 js动画 优缺点比较 我们经常面临一个抉择:到底使用JavaScript还是CSS动画,下面做一下对比 JS动画 缺点:(1)JavaScript在浏览器的主线程中运行,而主线程中还有其 ...
- css3动画和JS+DOM动画和JS+canvas动画比较
css3兼容:IE10+.FF.oprea(animation):safari.chrome(-webkit-animation) js+dom:没有兼容问题: js+canvas:IE9+:(性能最 ...
随机推荐
- synchronized 和 java.util.concurrent.locks.Lock 的异同 ?
主要相同点:Lock 能完成 synchronized 所实现的所有功能 主要不同点:Lock 有比synchronized 更精确的线程语义和更好的性能. synchronized 会自动释放锁,而 ...
- v-else-if(v-show)
<div id="app"> <div v-if="type === 'A'"> A </div> <div v-el ...
- @atcoder - CODE FESTIVAL 2017 Elimination Tournament Round 3 F@ Unicyclic Graph Counting
目录 @description@ @solution@ @accpeted code@ @details@ @description@ 求有多少 n 点 n 边的无向连通图,满足第 i 个点的度数为 ...
- Proving Equivalences(缩点+有环图变强连通分量)【tarjian算法】
Proving Equivalences 题目链接(点击) 参考博客(点击) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768 ...
- turtle 画一朵花
操纵海龟绘图有着许多的命令,这些命令可以划分为两种:一种为运动命令,一种为画笔控制命令1. 运动命令:forward(degree) #向前移动距离degree代表距离backward(degree ...
- Linux系统使用Nmon监控及分析系统性能
一.下载nmon(1)查看sever的内核版本: 命令:lsb_release -a执行结果:LSB Version: :base-4.0-amd64:base-4.0-noarch:c ...
- 套接字TCP控制台服务器程序代码示范
套接字TCP控制台服务器程序代码示范 https://blog.csdn.net/txwtech/article/details/90344081
- DES 加密解密 文件工具类
public class DESEncrypt { /** 加密工具 */ private Cipher encryptCipher = null; /** 解密工具 */ private Ciphe ...
- 龙芯团队完成CoreCLR MIPS64移植,在github开源
国产龙芯的软件生态之中.NET不会缺席,毕竟 C# 与 .NetCore/Mono 也是全球几大主流的编程语言和运行平台之一,最近一段时间听到太多的鼓吹政务领域不支持.NET, 大家都明白这是某些人为 ...
- skywalking与pinpoint全链路追踪方案对比
由于公司目前有200多微服务,微服务之间的调用关系错综复杂,调用关系人工维护基本不可能实现,需要调研一套全链路追踪方案,初步调研之后选取了skywalking和pinpoint进行对比; 选取skyw ...