[解決済み] Knockout.jsは準大規模データセットでは信じられないほど遅い
質問
私は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
のメソッドは、Knockout の
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メソッドから来る)をobservableコレクションにバインドする正しい方法でしょうか?
-
私は
push
は、私がそれを呼び出すたびに、バインドされたDOMオブジェクトを再構築するなど、何らかの重い再計算を行うものと思われます。 この再計算を遅らせるか、あるいは、すべてのアイテムを一度に押し込む方法はありますか?
必要であれば、さらにコードを追加することができますが、これが関連するものであることは間違いありません。 ほとんどの場合、私はサイトからKnockoutチュートリアルに従っただけです。
UPDATEです。
以下のアドバイスに従って、コードを更新しました。
this.loadData = function (data)
{
var mappedData = $.map(data, function (item) { return new ResultRow(item) });
this.projects(mappedData);
};
しかし
this.projects()
は400行で10秒程度かかります。 確かに、これがどの程度の速度になるかは分かりませんが
を使用せずに
Knockout を使用しない場合(DOM を通して行を追加するだけ)には、10 秒よりはるかに速くなるような気がします。
UPDATE 2です。
以下の他のアドバイスに従って、私は jQuery.tmpl を試してみました (KnockOut でネイティブにサポートされています)。このテンプレート エンジンは、わずか 3 秒強で約 400 行を描画します。 これは、スクロールするとより多くのデータが動的にロードされるようなソリューションを除けば、最良のアプローチのように思えます。
どのように解決するのですか?
コメントで提案されているとおりです。
Knockoutは(foreach, with)バインディングに関連した独自のネイティブテンプレートエンジンを持っています。また、他のテンプレートエンジン、すなわちjquery.tmplもサポートしています。読む はこちら をご覧ください。異なるエンジンでのベンチマークは行っていませんので、参考になるかどうかはわかりません。前のコメントを読むと、IE7では、あなたが求めているパフォーマンスを得るのに苦労するかもしれません。
余談ですが、KO は、誰かがそのためのアダプタを書いたのであれば、どんな js テンプレート エンジンでもサポートします。jquery tmpl は次のものに置き換えられる予定なので、他のものを試してみるとよいでしょう。 JsRender .
関連
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] JavaScriptで次の要素/前の要素を取得しますか?
-
[解決済み] javascriptで2つの数値を連結する方法は?
-
[解決済み] Chart.jsを使ってドーナツチャートの中にテキストを追加するには?
-
[解決済み] 文字列が空白であるかどうかをチェックする
-
[解決済み] オブジェクトの配列からReactコンポーネントをレンダリングする
-
[解決済み] react-routerのハッシュフラグメントからクエリパラメータを取得する
-
[解決済み] Node.jsのES6クラスをrequireで作る
-
[解決済み] JavaScript で `throw` の後に `return` をする必要がありますか?
-
[解決済み] Knockout.jsで観測可能なバインディングをクリア/削除する方法とは?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JavaScript で範囲を作成する - 奇妙な構文
-
[解決済み] Google maps API V3 - 同一地点に複数のマーカーを設置する。
-
[解決済み] React js 親コンポーネントから子コンポーネントの状態を変更する
-
[解決済み] Reactコンポーネントでthis.setStateを複数回使用するとどうなりますか?
-
[解決済み] jqueryはjavascriptのライブラリなのかフレームワークなのか?[クローズド]
-
[解決済み] javascriptで文字列から関数を作成する方法はありますか?
-
[解決済み] イテレータでmap()を使用する
-
[解決済み] Node.jsのES6クラスをrequireで作る
-
[解決済み] JavaScript で css プロパティを使用して HTML 要素の背景色を設定する方法
-
[解決済み] V8 Javascript エンジンのスタンドアロン実行