加载中

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

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

Angular 2 和 CycleJS 在 12 月 23 日加入 —

人们都想知道这个测试的重要性及其重要的原因。

快速跳转:ReactPreactInfernoVueAngular 2CycleJS总结

边城
边城
翻译于 2016/12/30 12:53
0

预览

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

实现者: 本文作者

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

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

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

实现者: Tero Parviainen,JavaScript 顾问

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

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

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

边城
边城
翻译于 2016/12/30 00:07
0

React


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

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

onMouseMove(event) {
    if (this.running) return;
    this.running = true;     // calculate stuff     this.setState({
        heightFactor: scaleFactor(y),
        lean: scaleLean(x)
    });
    this.running = false;
}

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

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

溪边九节
溪边九节
翻译于 2016/12/29 18:13
0

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

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

代码实现:diff on github

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

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

// src/Pythagoras.jsexport default class {
    render(props) {
        return Pythagoras(props);
    }
}

并启用去抖动异步渲染:

// src/index.js
import { options } from 'preact';
options.syncComponentUpdates = false;
 
//option 1:  rIC + setTimeout fallback
let timer;
options.debounceRendering = f => {
    clearTimeout(timer);
    timer = setTimeout(f, 100);
    requestIdleCallback(f);
};

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

tv_哇
tv_哇
翻译于 2017/01/06 11:00
0

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

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

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

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

// src/App.js
 
class App extends Component {
    // ...
    svgElemeRef = (domNode) => {
        this.svgElement = domNode;
    }
    // ...
    render() {
        // ..
 
    }

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

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

tv_哇
tv_哇
翻译于 2017/01/09 11:04
0

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

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

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

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

tv_哇
tv_哇
翻译于 2017/01/05 10:08
0

让我们来试一下吧。

把它分成 <template>,<script> 和 <style> 三个部分。这看起来有点像 JSX 或者 HTML,但实际上是模板带上了冒号前缀。

Vue 似乎采用了 React 的 put-it-all-together 组件化提示,但按语言拆分。虽然这看起来很简洁,但按照我以往的经验,实际操作其实很麻烦。

 App 组件还是跟过去类似,但它使用 data() 来定义默认的状态,用 $refs 代替 this.refs,用一个 name 属性代替了命名类本身,components 属性定义子节点,用 methods 属性来定义类方法。


溪边九节
溪边九节
翻译于 2017/01/03 18:22
1

虽然我不是 Angular 的粉丝,但我得承认它的确很好使用。

我不知道为什么,也许 TypeScript 的那些类型检查在转译后增加了运行时额外开销?

显然代码是重写了,Tero 需要将代码迁移到 TypeScript,这真厉害,我可做不到。

我很好奇,编程语言的隔阂会怎样影响你在网上找的随机库的可重用性。

代码看起来似乎包含很多文件。而 App 是分成 app.module.ts,app.component.ts,app.component.html 和 app.component.css 几个文件。和 Pythagoras 一样。

tv_哇
tv_哇
翻译于 2017/01/05 11:20
0

当你看到 Angular 的 html 文件时,意味着 Angular 坚持了一个文件对应一种语言的传统。

<div class="App-header">
  <h2>This is a dancing Pythagoras tree</h2>
</div>
<p class="App-intro">
  <svg #svg
        [attr.width]="width"
        [attr.height]="height"
        style="border: 1px solid lightgray">
    <g app-pythagoras
       [w]="baseW"
       [heightFactor]="heightFactor"
       [lean]="lean"
       [x]="width / 2 - 40"
       [y]="height - baseW"
       [lvl]="0"
       [maxlvl]="currentMax" />
  </svg>
</p>

这在 HTML 中看起来很有趣。

我对模块和组件之间区别的还没有完全理解。似乎模块定义了某些确定的引入,子组件等。但是每个组件仍然会定义它自己的 CSS 和 模板导入。

也因为我对这一块内容的了解不够深入,在此不对其用例的好处做过多描述。

溪边九节
溪边九节
翻译于 2017/01/10 20:13
0

这在我的设备上显示很流畅,可能是因为我刚刚看完 Angular 版本的演示。

Wayne 把所有东西都转译成 TypeScript,但似乎不是 CycleJS 要求的那样。尽管如此,他能保持与原始文件相同的简单结构,这一点深得人心。

在此我无法详细说明 Wayne 因 TypeScript 和 CycleJS 做的一些改变,他没有使用类定义 CycleJS 组件,其结构更像是在学校学的闭包结构。

export function App(sources: Sources): Sinks {
    const factorAndLean$ = sources.DOM.select('#the-svg') //...
 
    const args$ = xs.combine(factorAndLean$, xs.periodic(500) //...
 
    const pythagoras$ = Pythagoras(args$);
 
    const vtree$ = pythagoras$.map(x =&gt;
        div(Styles.App, [ // ...
 
    return {
        DOM: vtree$
    };
}

这需要时间适应。

tv_哇
tv_哇
翻译于 2017/01/09 11:30
0
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(19)

oreax
oreax

引用来自“oreax”的评论

>点击 GIF 可以看到它的代码
老是看到os这句话,一直以为gif代码就是可以用adobe photoshop/fireworks看到的帧~~~没想到不是!这翻译~~~做下链接也好嘛!不然就把这句话去掉嘛

引用来自“达尔文”的评论

感谢提醒,链接已加上。
👏 👍
小埋酱
小埋酱
前端花式斗图。。
AbbyCin
AbbyCin
66666666666666666666666666666666666666666
百世经纶之傲笑红尘
百世经纶之傲笑红尘
这前端花式斗图还真TMD有趣
达尔文
达尔文

引用来自“oreax”的评论

>点击 GIF 可以看到它的代码
老是看到os这句话,一直以为gif代码就是可以用adobe photoshop/fireworks看到的帧~~~没想到不是!这翻译~~~做下链接也好嘛!不然就把这句话去掉嘛
感谢提醒,链接已加上。
oreax
oreax
>点击 GIF 可以看到它的代码
老是看到os这句话,一直以为gif代码就是可以用adobe photoshop/fireworks看到的帧~~~没想到不是!这翻译~~~做下链接也好嘛!不然就把这句话去掉嘛
CHurricane
CHurricane

引用来自“Songlairui”的评论

作为一个材料渣,我更关注的是分形。
魔幻之翼
魔幻之翼

引用来自“魔幻之翼”的评论

没看到结果啊,是不是没翻译完?

引用来自“王练”的评论

有2页,记得翻页。
看到了,这分页控件....太靠右了...不够醒目😳
SwhGo_oN
SwhGo_oN

引用来自“Vian”的评论

这个分页说实话有点太隐蔽了,视觉习惯看左边,分页放在右边以为文章突然就结束了呢@红薯
+1
notreami
notreami
问题来了,实际开发中,什么场景选择什么框架呢?
返回顶部
顶部