Mac*_*Mac 8 javascript performance mobx
我从不同的资料中读到,mobx优于反应渲染器,并且比redux更快.但是,如果我做了几个测试,它表明向mobx observables添加新数据非常慢.在反应原生环境中每毫秒都很重要并且使用解决方案很困难,即使循环超过200个元素和填充数组需要超过100毫秒因为我真的很喜欢mobx我希望有人可以看看测试代码并给我一些提示 - 我是什么我做错了,如何提高绩效.
import {observable, transaction,autorun} from 'mobx';
class Runner {
list = observable([]);
run() {
const start = new Date().getTime();
transaction(() => {
for (let i = 0; i < 200; i++) {
this.list.push({
id: observable(i),
one: observable('1'),
two: '2',
three: 3,
x: 'xxxxx',
y: 'yyyyy',
z: 'zzzzz',
z1: 'zzzzz',
z2: 'zzzzz',
z3: 'zzzzz',
z4: 'zzzzz',
});
}
});
console.log('Execution time: ' + (new Date().getTime() - start) + 'ms services ');
}
}
const runner = new Runner();
autorun(() => console.log(runner.list));
runner.run();
Run Code Online (Sandbox Code Playgroud)
在我的笔记本电脑上,它需要大约120毫秒才能完成.没有可观察的时间,它需要不到1毫秒
mwe*_*ate 26
你没有做任何根本错误的事情(除了,正如罗伯特已经指出的那样,目前所有的属性都是可观察的,因为默认情况下可观察的是普通数据结构的recurses).
主要的是你还没有真正使用MobX :)你的测试结果是正确的,可观察的数据结构比普通结构贵得多.这有点比较苹果和橘子.或者为了更好的类比; 这就像基准化连接字符串以生成HTML而不是使用DOM来生成HTML.弦乐将永远胜利.
然而,在完整应用程序的大局中,情况有所不同.假设您需要更改元素的边框颜色.然后DOM可能会突然变得更有效率,因为它允许您只改变HTML的一个非常特定的部分,并且DOM足够聪明以确定需要在屏幕上重新绘制哪些像素.如果你只是一个简单的字符串,那将会更加困难.
MobX类似,不是从快速数据结构中获得它的性能,而是从它们的智能性.如果修改了一个可观察数组,MobX会精确查明哪些操作需要呈现哪些组件与您编写的任何计算一致.因为MobX能够建立更细粒度的"事件监听器",所以当你手工编写这类东西时你会这么做,而且因为MobX可以优化依赖树,人类程序员可能不会这么做,MobX可以非常快速.但是你必须从整个国家整个生命周期的大局看到它.如果你只是想非常快地创建一些对象和数组,那么没有什么能胜过普通数组和构造函数.
我建议您阅读@lavrton的这篇博客https://medium.com/@lavrton/how-to-optimise-rendering-of-a-set-of-elements-in-react-ad01f5b161ae#.enlk3n68g.它很好地演示了手动优化时跳槽所需的所有箍,只是为了接近MobX可以更新组件的速度.
我希望这能解释你的结果!
PS目前有一些已知的情况,在分类或清理大型集合时,MobX可能会很慢.这些将在即将发布的2.4.0版本中解决.
rob*_*lep 10
observable() 使你在数组中推送的所有值(递归地)都是可观察的,这可能不是你需要的.
例如,从您的示例代码可以看出,您只想观察id和a属性的更改,而不是其余的.在这种情况下,您可以在可观察数组上使用asFlat修饰符:
const { observable, autorun, transaction, asFlat } = mobx;
....
list = observable(asFlat([]));
Run Code Online (Sandbox Code Playgroud)
这将允许您观察到的变化list本身(新项目增加,项目中去除,等等),或在id和a列表项的属性,而不是休息.
这对我来说大大加快了测试速度:从35ms到大约5ms.
如果您在交易之外构建所有新项目,性能如何?
const start = new Date().getTime();
const newItems = [];
for (let i = 0; i < 200; i++) {
newItems.push({
id: observable(i),
one: observable('1'),
two: '2',
three: 3,
x: 'xxxxx',
y: 'yyyyy',
z: 'zzzzz',
z1: 'zzzzz',
z2: 'zzzzz',
z3: 'zzzzz',
z4: 'zzzzz',
});
}
transaction(() => {
Array.prototype.push.apply(this.items, newItems)
});
Run Code Online (Sandbox Code Playgroud)
然后尝试不使用observablearoundid和one,然后尝试不使用事务(因为现在对...的所有更改都this.items在一次调用中完成Array.prototype.push)
| 归档时间: |
|
| 查看次数: |
4638 次 |
| 最近记录: |