我刚刚开始使用 Knockout.js (一直想尝试一下,但现在我终于找到了一个借口!)然而,当把一个表绑定到一个相对较小的数据集(大约400行左右)时,我遇到了一些非常糟糕的性能问题。
在我的模型中,我有以下代码:
this.projects = ko.observableArray( [] ); //Bind to empty array at startup
this.loadData = function (data) //Called when AJAX method returns
{
for(var i = 0; i < data.length; i++)
{
this.projects.push(new ResultRow(data[i])); //<-- Bottleneck!
}
};
问题是上面的 for
循环大约需要30秒左右,大约有400行。但是,如果我将代码更改为:
this.loadData = function (data)
{
var testArray = []; //<-- Plain ol' Javascript array
for(var i = 0; i < data.length; i++)
{
testArray.push(new ResultRow(data[i]));
}
};
然后 for
循环在眨眼间完成。换句话说,Knokout 的 observableArray
对象的 push
方法非常慢。
以下是我的模板:
<tbody data-bind="foreach: projects">
<tr>
<td data-bind="text: code"></td>
<td><a data-bind="projlink: key, text: projname"></td>
<td data-bind="text: request"></td>
<td data-bind="text: stage"></td>
<td data-bind="text: type"></td>
<td data-bind="text: launch"></td>
<td><a data-bind="mailto: ownerEmail, text: owner"></a></td>
</tr>
</tbody>
我的问题:
push
时,它都会进行一些大量的重新计算,比如重新构建绑定的 DOM 对象。有没有什么办法可以延缓这次撤销,或者可以一次性把我所有的东西都放进去?如果需要,我可以添加更多的代码,但我很确定这是相关的。在大多数情况下,我只是按照敲除教程从网站。
更新:
根据下面的建议,我更新了我的代码:
this.loadData = function (data)
{
var mappedData = $.map(data, function (item) { return new ResultRow(item) });
this.projects(mappedData);
};
但是,对于400行,this.projects()
仍然需要大约10秒。我承认我不确定这将是多快的 没有敲除(只是通过 DOM 添加行) ,但我有一种感觉,它会比10秒快得多。
更新2:
根据下面的其他建议,我给了 JQuery tmpl一个尝试(KnokOut 本机支持) ,这个模板引擎将在3秒钟内绘制大约400行。这似乎是最好的方法,但缺乏一种在滚动时动态加载更多数据的解决方案。