34

ブラウザー内で DOM ツリーをディープ クローンする最もパフォーマンスの高い方法を見つけようとしています。

私が始めるなら

var div = document.getElementById("source");
var markup = div.innerHTML;

何が速くなるか、

var target = div.cloneNode(true);

また

var target = document.cloneNode(false);
target.innerHTML = markup;

ここではブラウザ プラットフォームが大きな違いを生む可能性があることを理解しています。

4

2 に答える 2

56

テストしましょう!

次のコードを StackOverflow の質問ページのコピーに追加しました (最初に既存のスクリプトを削除し、timeit()毎回 s の 1 つをコメント解除してゼロから実行し、100 ops を 3 回実行します。

function timeit(f) {
    var start= new Date();
    for (var i=100; i-->0;) {
        f();
    }
    return new Date()-start;
}

var c= document.getElementById('content');
var clones= [];

//alert('cloneNode: '+timeit(function() {
//    clones.push(c.cloneNode(true));
//}))

//alert('innerHTML: '+timeit(function() {
//    var d= document.createElement('div');
//    d.innerHTML= c.innerHTML;
//    clones.push(d);
//}))

Core 2 Q9300 上の VirtualBox で実行した結果は次のとおりです。

IE7
cloneNode: 3238, 3235, 3187
innerHTML: 8442, 8468, 8552

Firefox3
cloneNode: 1294, 1315, 1289
innerHTML: 3593, 3636, 3580

Safari3
cloneNode: 207, 273, 237
innerHTML: 805, 818, 786

Chrome1
cloneNode: 329, 377, 426
innerHTML: 2327, 2536, 2865

Opera10
cloneNode: 801, 791, 771
innerHTML: 1852, 1732, 1672

そのcloneNode(true)ため、コピーよりもはるかに高速ですinnerHTML。もちろん、それは常にそうなるつもりでした。DOM をテキストにシリアル化し、HTML から再解析するのは大変な作業です。DOM の子操作が通常遅い理由は、それらを 1 つずつ挿入/移動しているためです。などの一度に DOM 操作をcloneNode行う必要はありません。

Safari は操作をinnerHTML驚くほど迅速に行うことができますが、それでもそれほど速くはありませんcloneNode。IEはさすが犬。

そのため、質問が実際に何をしているのかを考慮せずに、innerHTML の方が明らかに高速であると言ったすべての人に auto -1 を返します。

はい、jQuery は innerHTML を使用してクローンを作成します。ただし、高速だからではありません—ソースを読んでください:

// IE copies events bound via attachEvent when
// using cloneNode. Calling detachEvent on the
// clone will also remove the events from the orignal
// In order to get around this, we use innerHTML.

jQuery はElement.attachEvent()独自のイベント システムを実装するために使用するため、当然、そのバグを回避する必要があります。必要がない場合は、オーバーヘッドを回避できます。

余談ですが、jQuery をベスト プラクティスの頂点に掲げるのは、特に次の行を考えると、少し間違っていると思います。

html.replace(/ jQuery\d+="(?:\d+|null)"/g, "")

そうです — jQuery は独自の任意の属性を HTML 要素に追加し、クローンを作成する (または、メソッドなどを介してマークアップにアクセスできるようにする) ときにそれらを削除する必要があります$().html()。これは十分に醜いですが、それを行う最善の方法は正規表現を使用して HTML を処理することであると考えています。 JS フレームワーク エバー。

jQuery1="2"テキスト コンテンツのどこにも文字列がないことを願っています。ありがとう、jQuery!したがって、オフトピックは脇に置きます。

于 2009-03-24T17:59:59.990 に答える