淘汰赛3.4.0 deferUpdates和重新评估计数

时间:2016-03-29 10:27:06

标签: knockout.js

我正在将一个广泛依赖于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来增加?

提前感谢大家

请注意:

  • 我不想使用rateLimit扩展器,也不指定固定的时间段,因为我不确定这是否只提供一次重新评估。
  • 我宁愿不使用deferredUpdates单独扩展每个单独的observable,因为我有数百个,并且我无法准确预测代码将在何处中断

1 个答案:

答案 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中所需的大多数优化 - 唯一令人烦恼的是,在某些特殊情况下其中一些优化必须被删除。