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话题中学习更多:

  • Jank Free

  • Rendering Without Lumps

  • Faster Websites

    本文转载自:众成翻译
    译者:凯小凯
    审校: betsey
    链接:http://www.zcfy.cc/article/4635
    原文:https://davidwalsh.name/css-js-animation

转载于:https://www.cnblogs.com/wwhhq/p/8157430.html

CSS vs. JS Animation: 哪个更快相关推荐

  1. CSS 和 JS 动画哪个更快

    基于Javascript的动画暗中同CSS过渡效果一样,甚至更加快,这怎么可能呢?而Adobe和Google持续发布的富媒体移动网站的性能可媲美本地应用,这又怎么可能呢? 本文逐一遍览了基于Javas ...

  2. 自从用了Less 编写css,你比以前更快了~

    之所以用这个标题呢,主要是最近调侃杰伦太有意思了. 好吧,开个玩笑而已. 如果你了解过Less,并对之很熟悉,就不用往下看了. 如果你没用过,恭喜,这是一个入门级的教程,学会了它,可以为你节省10%的 ...

  3. css动画和js动画_CSS与JS动画:哪个更快?

    css动画和js动画 How is it possible that JavaScript-based animation has secretly always been as fast - or ...

  4. css和js优化_如何为更快的站点优化CSS和JS

    css和js优化 This article was sponsored by Aussie Hosting. Thank you for supporting the partners who mak ...

  5. 让你的 Node.js 应用跑得更快的 10 个技巧

    Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异 ...

  6. 蜂鸟视图JS SDK v3.0:五大亮点,打造更小更快的可视化地图应用

    近期,蜂鸟视图发布了FengMap JavaScript SDK v3.0版本,该版本在不减少任何功能的情况下,对原有的渲染内核进行了优化,使得数据加载性能提升了30%,渲染性能提升了25%,包体大小 ...

  7. web前端面试题完美整理/涵盖html,CSS、JS、浏览器、Vue、React、移动web。

    本篇文章整理总结了一些前端面试题,涵盖面很广,并且面的都是知名大厂,所以这些题还是很有代表性的,都掌握以后一面基础面应该没什么问题,二面也能应付大半,奉上: css相关 更多教程:https://su ...

  8. 前端基础(HTML、CSS、JS)

    前端基础(HTML.CSS.JS) 1 HTML 1.1 文件标签 1.2 排版标签 1.3 字体标签 1.4 列表标记 1.4.1 有序列表 1.4.2 无序列表 1.5 图片标签 1.6 超链接标 ...

  9. web前端知识点总结html,css,js,vue,react/面试题会经常问到

    一阶段 1.网络中使用最多的图片格式有哪些 gif 支持动画,只有全透明和不透明两种模式,只有256种颜色 jpg 采用有损压缩算法,体积较小,不支持透明,不支持动画 png 采用有损压缩算法,体积也 ...

最新文章

  1. springboot整合vue小试牛刀
  2. 【AI初识境】给深度学习新手开始项目时的10条建议
  3. 【Lucene4.8教程之四】分析
  4. Quartz.net官方开发指南 第九课: JobStore
  5. response.sendRedirect使用注意事项 .
  6. oracle集群监听启动,在RAC中lsnrctl和srvctl操作监听区别
  7. 使用electron-vue创建项目卡顿的问题
  8. ROS笔记(17) Gazebo
  9. redis应用场景java实例_redis使用场景和java测试案例
  10. OpenCV-实现背景分离(可用于更改证件照底色)
  11. python---之hasattr()
  12. Java革新大提速 Chrome 54终结YouTube的Flash内嵌技术
  13. C# 代码实现浏览PDF文件
  14. 常用电感封装与电流关系
  15. 对“努力就能成功”的一点思考
  16. 计算机道德 英语作文,关于道德英语作文
  17. 星际争霸2-数据编辑器-菜鸟入门
  18. 未成年人勿进 谨以献给1980~1990出生的人(一)
  19. 2022年最新浙江机动车签字授权人模拟试题及答案
  20. 国内也可以用Chatgpt了!无需注册!无需科技!

热门文章

  1. 从特急到难产 光伏增补项目抢不抢630?
  2. Fragment 和 FragmentActivity的使用
  3. 添加Net4CollectionTypeFactory的原因
  4. 从jQuery的缓存到事件监听
  5. Node.js v0.10版本发布
  6. 收集到的一些网络工程师面试题 和大家分享下
  7. vmware 添加 磁盘 空间
  8. 微软云计算业务增长,或成全球最具价值上市公司
  9. MyBatis的扩展点(plugins)
  10. 视频直播常见问题与解决办法汇总【系列二—直播截图】