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
上記のループが約400行で約30秒かかることです。ただし、コードを次のように変更すると、次のようになります。
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
ループは瞬く間に完了します。言い換えれば、push
ノックアウトのobservableArray
オブジェクトのメソッドは信じられないほど遅いです。
これが私のテンプレートです:
<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>
私の質問:
- これは、私のデータ(AJAXメソッドから取得)を監視可能なコレクションにバインドする正しい方法ですか?
push
バインドされたDOMオブジェクトを再構築するなど、呼び出すたびにかなりの再計算を行うことを期待しています。この再計算を遅らせる方法、またはすべてのアイテムを一度にプッシュする方法はありますか?
必要に応じてコードを追加できますが、これが関連性があると確信しています。ほとんどの場合、私はサイトのノックアウトチュートリアルに従っていました。
更新:
以下のアドバイスに従って、コードを更新しました。
this.loadData = function (data)
{
var mappedData = $.map(data, function (item) { return new ResultRow(item) });
this.projects(mappedData);
};
ただし、this.projects()
400行の場合でも約10秒かかります。ノックアウトなし(DOMを介して行を追加するだけ)でこれがどれほど速くなるかはわかりませんが、10秒よりもはるかに速いと感じています。
更新2:
以下の他のアドバイスに従って、jQuery.tmplにショットを与えました(これはKnockOutによってネイティブにサポートされています)。このテンプレートエンジンは、3秒強で約400行を描画します。これは、スクロールするにつれてより多くのデータを動的にロードするソリューションを除いて、最良のアプローチのように思われます。