我正在将一个广泛依赖于Knockout.js的复杂Web应用程序迁移到新的3.4.0版本,以便能够实现组件,并获得新deferUpdates选项提供的新性能改进,阅读Knockout文档:
使用延迟更新可确保计算出的可观察量和绑定 只有在它们的依赖关系稳定后才会更新。
现在,令人惊讶的是,我的情况是我的依赖观察值被重新评估的次数比之前更多,这导致比以前更多的UI重绘。
这是observableArrays的经典优化示例,只会在较旧的KO版本和新的3.4.0 中打开一个重新评估,而不启用 deferUpdates:
this.items = ko.observableArray();
this.addNewData = function() {
var items = ko.utils.arrayMap(Items, function(item) {
return new Item(item.name, item.priority);
});
//take advantage of push accepting variable arguments
self.items.push.apply(self.items, items);
};
this.addNewData();
现在,通过设置:
ko.options.deferUpdates = true;
有两个重新评估,一个是observableArray创建:
this.items = ko.observableArray();
和第二个提供数据时,通过调用addNewData()。
小提琴:http://jsfiddle.net/kkrgjbsr/
相反,为了更详细地解释发生了什么,在observableArray初始化之后只会导致一次重新评估,因为它对我有好处:
this.items = ko.observableArray([
new Item(Items[0]),
new Item(Items[1]),
...and so on
]);
有人可以请解释如何保持deferUpdates的性能提升,因为我的应用程序中有一部分我绝对需要它,同时避免这些不必要的重新评估?
顺便说一句,有没有办法在整个应用程序中跟踪重新评估计数会通过启用deferUpdates来增加?提前感谢大家
请注意:
答案 0 :(得分:2)
好的,这就是我发现的:
ko.options.deferUpdates = true 仅在viewmodel初始化期间再创建一次重新评估。
要将数据传递给observableArray构造函数,只需使用实用程序函数arrayMap - 没有麻烦:
this.items = ko.observableArray(ko.utils.arrayMap(Items, function(item) {
return new Item(item.name, item.priority);
}));
在我的特殊情况下,增加的重新评估计数的不必要的副作用难以识别,因为它只影响了UI重绘 - 而不是数据 - 并导致意外的性能下降。
此外,我还测试了rniemeyer的小提琴"重新评估计算的观察者"随着新的3.4.0淘汰赛版本和deferUpdates开启 - 甚至是"添加新的错误"按钮只显示1次重新评估计数(对不起,如果我测试了明显的那些)。
现在,我总是打开新选项deferUpdates,因为这是一个出色且不可或缺的性能改进,并且不再需要旧版KO中所需的大多数优化 - 唯一令人烦恼的是,在某些特殊情况下其中一些优化必须被删除。