質問
大量の HTML を挿入する方法について嫌な予感がしました。次の結果が得られたと仮定しましょう:
var html="<table>..<a-lot-of-other-tags />..</table>"
そしてこれを入れたいのです
$("#mydiv")
以前に私は次のようなことをしました
var html_obj = $(html);
$("#mydiv").append(html_obj);
jQueryが解析しているというのは正しいですか? html
DOMオブジェクトを作成するには?さて、これはどこかで読んだ内容です (アップデート: jQuery は HTML を解析して DOM ツリー全体を手動で作成する、ということを読んだつもりです。それはナンセンスですよね?!), ので、コードを変更しました。
$("#mydiv").attr("innerHTML", $("#mydiv").attr("innerHTML") + html);
速く感じますね?そして、これは次と同等であるというのは正しいでしょうか。
document.getElementById("mydiv").innerHTML += html
?それともjqueryがバックグラウンドで追加の高価なことを実行しているのでしょうか?
代替案も学びたいと思っています。
解決
innerHTML は驚くほど高速で、多くの場合、これを設定するだけで最高の結果が得られます (私なら、単に append を使用します)。
ただし、「mydiv」にすでに多くのコンテンツがある場合は、ブラウザーにそのすべてのコンテンツ (以前に存在していたすべてのコンテンツと新しいコンテンツのすべて) を再度解析してレンダリングするよう強制することになります。 代わりにドキュメントのフラグメントを「mydiv」に追加することで、これを回避できます。
var frag = document.createDocumentFragment();
frag.innerHTML = html;
$("#mydiv").append(frag);
この方法では、新しいコンテンツのみが解析され (不可避に)、既存のコンテンツは解析されません。
編集:私の悪い...innerHTML がドキュメント フラグメントで十分にサポートされていないことがわかりました。どのノード タイプでも同じ手法を使用できます。たとえば、ルート テーブル ノードを作成し、そこに innerHTML を挿入できます。
var frag = document.createElement('table');
frag.innerHTML = tableInnerHtml;
$("#mydiv").append(frag);
他のヒント
何を避けようとしていますか?「嫌な予感」というのは非常に曖昧なものです。「DOM は遅い」と聞いて「DOM を避けよう」と決めた場合、これは不可能です。innerHTML を含め、ページにコードを挿入するすべての方法で DOM オブジェクトが作成されます。DOM は、ブラウザのメモリ内のドキュメントの表現です。あなた 欲しい 作成される DOM オブジェクト。
「DOM は遅い」と言われる理由は、 document.createElement()
, は、要素を作成するための公式 DOM インターフェイスですが、一部のブラウザでは非標準の innerHTML プロパティを使用するよりも遅くなります。これは、DOM オブジェクトを作成することが悪いという意味ではありません。 必要 DOM オブジェクトを作成しないと、コードは何も実行されません。
DOM フラグメントの使用に関する答えは正しい方向にあります。大量の HTML オブジェクトを常に DOM に挿入している場合は、フラグメントを使用すると速度が向上します。John Resig によるこの投稿は、それを非常によく説明しています。http://ejohn.org/blog/dom-documentfragments/
アイテムを追加する最速の方法
DOM ツリーに追加する最も速い方法は、すべての追加を 1 つの DOM フラグメントにバッファリングしてから、その dom フラグメントを dom に追加することです。
これは私がゲーム エンジンで使用している方法です。
//Returns a new Buffer object
function Buffer() {
//the framgment
var domFragment = document.createDocumentFragment();
//Adds a node to the dom fragment
function add(node) {
domFragment.appendChild(node);
}
//Flushes the buffer to a node
function flush(targetNode) {
//if the target node is not given then use the body
var targetNode = targetNode || document.body;
//append the domFragment to the target
targetNode.appendChild(domFragment);
}
//return the buffer
return {
"add": add,
"flush": flush
}
}
//to make a buffer do this
var buffer = Buffer();
//to add elements to the buffer do the following
buffer.add(someNode1);
//continue to add elements to the buffer
buffer.add(someNode2);
buffer.add(someNode3);
buffer.add(someNode4);
buffer.add(someN...);
//when you are done adding nodes flush the nodes to the containing div in the dom
buffer.flush(myContainerNode);
このオブジェクトを使用すると、Firefox 4 で 1 秒あたり最大 1000 個のアイテムを画面に最大 40 回レンダリングできます。
ここでは使用例を示します。
まず、各メソッドを 100 回または 1,000 回実行するのにかかる時間を計算するスクリプトを作成します。
繰り返しが何らかの形で最適化されないようにするには、--私は JavaScript エンジンの専門家ではありません--毎回、挿入する HTML を変更します。たとえば、特定のテキストに「0001」、「0002」、「0003」を入れるなどです。テーブルのセル。
巨大な文字列を作成し、この文字列を jquery で追加します。私にとっては、うまく、速く動作します。
代替案に興味があるとおっしゃっていましたね。のリストを見てみると、 DOM 関連の jQuery プラグイン プログラムによる DOM ツリーの生成に特化したものがいくつかあります。たとえば、を参照してください スーパーフライドム または DOM 要素作成者;しかし他にもあります。