9

複数の dom 操作を行うと、複数の再描画が強制されるため、悪いことはわかっています。

すなわち:

$('body').append('<div />')
         .append('<div />')
         .append('<div />')
         .append('<div />');

代わりに、より良い方法は明らかに次のとおりです。

$('body').append('<div><div></div><div></div><div></div><div></div></div>');

しかし、私は仮想操作に興味があります

すなわち:

$('<div />').append('<div />')
            .append('<div />')
            .append('<div />')
            .append('<div />')
            .appendTo('body');

それはまだ悪いですか、明らかに関数を数回呼び出すことでいくらかのオーバーヘッドが発生しますが、パフォーマンスに重大な影響があるのでしょうか?


私が尋ねる理由はこれです:

var divs = [
    {text: 'First',  id: 'div_1', style: 'background-color: #f00;'},
    {text: 'Second', id: 'div_2', style: 'background-color: #0f0;'},
    {text: 'Third',  id: 'div_3', style: 'background-color: #00f;'},
    {text: 'Fourth', id: 'div_4', style: 'background-color: #f00;'},
    {text: 'Fifth',  id: 'div_5', style: 'background-color: #0f0;'},
    {text: 'Sixth',  id: 'div_6', style: 'background-color: #00f;'}
];

var element = $('<div />');

$.each(divs, function(i,o){
    element.append($('<div />', o));
});

$('body').append(element);

divs 配列が、フォームを記述するデータベース テーブル (この例では div を使用していますが、入力に簡単に置き換えることができます) または類似のものから取得されたと想像してください。

または、「推奨」バージョンを使用すると、次のようになります。

var divs = [
    {text: 'First',  id: 'div_1', style: 'background-color: #f00;'},
    {text: 'Second', id: 'div_2', style: 'background-color: #0f0;'},
    {text: 'Third',  id: 'div_3', style: 'background-color: #00f;'},
    {text: 'Fourth', id: 'div_4', style: 'background-color: #f00;'},
    {text: 'Fifth',  id: 'div_5', style: 'background-color: #0f0;'},
    {text: 'Sixth',  id: 'div_6', style: 'background-color: #00f;'}
];

var element = '<div>';

$.each(divs, function(i,o){
    element += '<div ';

    $.each(o, function(k,v){
        if(k != 'text'){
            element += k+'="'+v+'" ';
        }            
    });

    element += '>'+o.text+'</div>';

});

element += '</div>';

$('body').append(element);
4

4 に答える 4

10

まず、このような潜在的なパフォーマンス ヒットについて読むのは素晴らしいことですが、問題があるかどうかを確認するために常に測定することから始める必要があります。

問題を認識できない場合は、最も読みやすいコードを記述してください。

問題を認識できたら、測定、変更、および測定します。

appendToあなたが投稿した最後の例には、まだ DOM に書き込まれていない要素が含まれているため、DOMに要素を追加するまで再描画は行われません。

2 番目と 3 番目の例の速度の違いを捉えることができれば、私は非常に驚きます。また、それらのいずれかに大きな違いがあることを確認できれば、非常に驚​​くでしょう。

于 2012-11-02T23:39:22.740 に答える
1

実行時の古き良きマークアップ生成に何が起こったのでしょうか? 真剣に、何が起こったのですか?

読みやすさの重要性に関する @Sohnee の指摘には同意しますが、DOM 操作は、ブラウザーが実行できる最も高価な操作の一部です。マークアップの文字列を維持するオプションを使用すると、完全に読みやすくなり、ユーザー エクスペリエンスが無視できないほど向上します。

このjsperfでは、実行時に 10x100 のテーブルを作成しています。これは、データのページ付けにとって完全に合理的です (そして、最も複雑なシナリオではありません)。最近のバージョンの Chrome を実行しているクアッド コア マシンでは、マークアップ キャッシュの 3 ミリ秒とは対照的に、直接 DOM 操作スクリプトが完了するまでに 60 ミリ秒かかります。

これは私のセットアップでは見分けがつかないほどの違いですが、企業のファイアウォールの内側に座っていて、古いバージョンの IE を使用せざるを得ない貧弱な数字処理担当者についてはどうでしょうか? 必要な DOM 操作がより重く、属性操作や再描画/再フローを積極的に強制する場合はどうなるでしょうか?

私が言いたいのは、何らかの JavaScript を最適化したい場合、ここから始めるのは悪くないということです。

于 2012-11-03T06:49:25.723 に答える
1

ノードを追加するときのパフォーマンスが本当に心配な場合は、ドキュメントフラグメントを使用する必要があります。これらにより、再描画せずに要素を dom に追加できます。John Resign には、このトピックに関する優れた記事があります。彼は、パフォーマンスが 200 ~ 300% 向上したことに注目しています。アプリの 1 つにドキュメントフラグメントを実装しましたが、彼の主張を確認できます。

于 2012-11-02T23:41:47.403 に答える
0

この種のコードがパフォーマンスのボトルネックになり始めたら、DOM 操作の代わりにテンプレートを使用する必要があると思います。

しかし、ドキュメント フラグメント アプローチ (すべてのノードを DOM にアタッチする前に切り離されたノードに入れる) を使用すると、ほとんどの場合は高速になり、遅くなることはほとんどありません。

于 2012-11-03T00:12:32.603 に答える