专栏名称: OSC开源社区
OSChina 开源中国 官方微信账号
目录
相关文章推荐
程序猿  ·  41岁DeepMind天才科学家去世:长期受 ... ·  15 小时前  
程序员的那些事  ·  OpenAI ... ·  15 小时前  
程序员的那些事  ·  印度把 DeepSeek ... ·  昨天  
程序员的那些事  ·  惊!小偷“零元购”后竟向 DeepSeek ... ·  2 天前  
程序员的那些事  ·  成人玩偶 + ... ·  4 天前  
51好读  ›  专栏  ›  OSC开源社区

用2048个 SVG 节点做动画:这些 MVVM 框架谁的性能更好?

OSC开源社区  · 公众号  · 程序员  · 2017-01-19 08:36

正文


OSC 协作翻译

原文: Animating 2048 SVG nodes in React, Preact, Inferno, Vue, Angular 2, and CycleJS – a side-by-side comparison

链接: https://swizec.com/blog/animating-svg-nodes-react-preact-inferno-vue/swizec/7311

译者: tv_哇, 无若, 边城, Tocy


曾经想知道如果播放一个由 2048 个 SVG 节点组成的动画,使用哪个前端框架会更流畅?这里有一些 GIF 动画展示。


同样是毕达哥拉斯树动画,同样是在2012年中的视膜屏 MacBook Pro 中。所有动画都使用 LICEcap 录制,使用常规设置,可以在 Chrome、Spotify、Emacs 中运行。点击“阅读原文” 可以看到它的代码。


预览


很多 GIF 都能在它们的 GitHub 上找到链接。甚至可以复制库然后在本地运行,非常有趣。

实现者: 本文作者


实现者: Jason Miller,Preact 的创造者


实现者: Dominic Gannaway,Inferno 的创造者


实现者: Evan You,Vue 的创造者


实现者: Tero Parviainen,JavaScript 顾问


实现者: Wayne Maurer,Lambda IT 的创始人


感谢 Jason、Dominic 和 Evan 创建分支,同样感谢 Tero 和 Wayne 加入了他们自己的版本。如果有人能不使用框架,直接用原生 JavaScript 实现,那一定很酷。


让我们通过代码了解它是如何工作的。


React


在 Jason 和 Evan 的提示下,对鼠标事件进行节流能使 demo 更快。结果证明原始版本的动画树运行缓慢不是 React 自身的原因,而是每个刷新周期内太多的请求让渲染引擎不堪重负。


我尝试过对 requestAnimationFrame 进行节流,但是实际效果并不好。相比之下限制 React 重绘周期的方法就简单而有效。


先检查是否在进行更新,如果没有就手动更新。这个之所以生效是因为 React 的引擎是同步的。

要是没有  React Fiber,我觉得它可能会挂掉。¯\(ツ)/¯


Preact


Jason 用 preact-compat 层使得 Preact 看起来很像 React。这很有可能影响它的性能。


我喜欢 Preact 的示例是因为它使用异步渲染让效果更流畅。鼠标移动后,你能看到重绘周期滞后而产生的神奇效果。我很喜欢这效果。


代码实现:diff on github

在 package.json 中,他添加了 preact,preact-compat 和 React 库的 preact-compat 克隆,后者能让你不需要改变 imports。


他把无状态的 Pythagoras 功能组件转换成一个有状态的组件从而实现异步渲染。


并启用去抖动异步渲染:


我最喜欢 Preact 的部分是,它可以作为 React 的替代品,并且运行良好。从我目前的应用程序来看,它的性能优化会有不错的发展前景。


Inferno


你可以用 Inferno 替代 React。Dominic 说这会影响性能,所以他就创建了新分支。你可以在 github 上比对差异。


Dominic 把所有相关的 react-scripts 改成 inferno-scripts。他同时也把 react 改成 inferno-beta36,这意味着我的CTO肯定不允许我在生产环境中使用它。


从上面看出,它最主要的是各种导入的改变——React 变成 Inferno,还把许多类方法改成绑定箭头函数。我不知道这是出于风格的选择还是 Inferno 的需要。


他也把基于字符串引用改成基于回调引用,Inferno 因为性能的原因不能使用基于字符串引用。取而代之,我们可以用 D3 来检测 SVG 上的鼠标位置。这比起我们自己弄简单很多。


在 Pythagoras 核心组件上,他添加两个 Inferno 特殊属性:noNormalize 和 hasNonKeyedChildren.


从八天前的 issue 知道,noNormalize 是提高性能的一个基准, hasNonKeyedChildren 的作用尚不明确。我猜想这两个属性都是用来为虚拟 DOM diffing 算法优化性能。


Vue


这项工作的工作量比较大,是由Evan和树的创作者Phan An 完成的。


Vue 并没有打算模仿 React 的 API,它拥有自己的一套代码。我想通过 github 展示它们之间的差异,但这比较繁琐。我建议你去 Github 自行查看。


你可以识别出 Pythagoras 核心组件。Evan 使用了 transform-vue-jsx,使得 JSX 能在 Vue 里使用。


main.app 文件在此,你可以点击查看然后理解其代码。


让我们来试一下吧。


把它分成







请到「今天看啥」查看全文