我想在这里找到一个好的答案,而不是寻找任何答案,“你试过X吗?”,宁愿有一个知识渊博的答案。
我有一个可观察的数组,我用它来填写图表。可观察数组最多可包含10k个POJO,这些POJO是从本地缓存中的Breeze.js中检索的。当我第一次出去从服务器获取数据,然后对本地缓存进行调用时,它几乎立即返回。
在下次通话中,它会以指数方式变慢。返回的对象不是每个可观察对象,也不包含observable,因为我正在执行Breeze查询,选择它们是POJO。问题是,当我返回并继续获得相同的数据集时,它们会继续变得越来越慢。几乎让我想到我在某种程度上在可观察数组中创建了内存泄漏。
<h1>There are <span data-bind="text: chartData().length"></span> chart items</h1>
var chartData = ko.computed(function () {
var myArray = ko.observableArray();
var params = { xmin: xMin(), xmax: xMax() };
if (!initialized) { return myArray(); }
datacontext.getData(myArray, params.xmin, params.xmax false);
return myArray();
}).extend({ throttle: 2000 });
if (!forceRemote) {
var thisData = manager.executeQueryLocally(query);
myObservable([]);
var myArray = myObservable();
ko.utils.arrayPushAll(myArray, thisData);
return myObservable.valueHasMutated();
}
我根据另一个SO.com问题的建议尝试了arrayPushAll和值变异,但它似乎没有设置myObservable([])然后将其设置为等于thisData更快。
由于数据集很大,我希望将其减少到尽可能少的重新计算。
我将xmin和xmax设置为params的原因是使计算依赖于两个observable ...
答案 0 :(得分:3)
我自己发现Knockout在过滤时很慢,特别是在IE8上。不幸的是,这对我来说仍然是支持的浏览器:-(问题是我正在使用复杂的html模板过滤大型集合.IE8渲染引擎非常适合并且不断抛出“慢速运行脚本”警报。
我通过使用CSS'display'属性解决了这个问题。我为集合中的每个元素添加了一个可见的Observable,以及以下数据绑定。 (其中hidden是一个带有display:none;的css类)。
data-bind="css:{'hidden':visible()===false}"
然后你要做的就是遍历集合并根据需要设置属性。这对我的情况产生了巨大的影响。
答案 1 :(得分:2)
简化您的计算可观察量。很少有理由在计算的observable中创建一个observable。
var chartData = ko.computed(function () {
var min = xMin(), max = xMax(); // ensure we have a dependency
return !initialized ? [] : datacontext.getData(min, max, false);
}).extend({ throttle: 2000 });
查询只需要返回数据:
if (!forceRemote) {
var thisData = manager.executeQueryLocally(query);
return thisData;
}
编辑:
假设您已经加载了所有数据并将其存储在数组中,您计算的observable可以使用ko.utils.arrayFilter
来计算过滤结果:
var chartData = ko.computed(function () {
var min = xMin(), max = xMax(); // ensure we have a dependency
return !initialized ? [] : ko.utils.arrayFilter(dataArray, function(item) {
return item.x >= min && item.x <= max;
});
});