2

次のように2000行のデータがあります

<div class="rr cf">
    <span>VLKN DR EXP</span>
    <span>01046</span>
    <span>VELANKANNI</span>
    <span>20:30</span>
    <span>DADAR</span>
    <span>10:00</span>
</div>

ボタンをクリックすると、その中のテキストがチェックされ、各行の表示がblockまたはに更新されますnone。これを行うコードは

$('.rr').each(function(){
    this.style.display="block";
});

var nodes = $(".rr");
for(var i=0;i < nodes.length; i++) {
     // if data found
         nodes.get(i).style.display="block";
     // else
         nodes.get(i).style.display="none";
}

これはおそらく非常に遅いようです。ページを強制終了するためのChromeアラートボックスが表示されます。

何か案は?ここでどのような最適化を行うことができますか?

4

5 に答える 5

3

ローカル変数とループ


ループのパフォーマンスを向上させるもう1つの簡単な方法は、全長に向かってインクリメントするのではなく、イテレータを0に向かってデクリメントすることです。この単純な変更を行う と、各反復の複雑さに応じて、元の実行時間を最大50%節約できます。

取得元:http ://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html

  • ループが毎回計算する必要がないように、をローカル変数nodes.lengthとして保存してみてください。
  • また、nodes.get(i)ローカル変数に格納して、そのデータに頻繁にアクセスする場合に時間を節約することもできます。
  • 順序が重要でない場合は、forループを0に向かってデクリメントすることを検討してください。
  • jQueryのeach()ループは、自分でセットをループするよりも少し遅くなります。ここで、明らかな違いがあることがわかります。

非常に簡単な

私の例では、ループをループに凝縮していることがわかりwhileます。

var nodes = $(".rr span");
var i = nodes.length;

while(i--){ 
  if(i%2 === 0){
    nodes.get(i).style.color = "blue";}
}​

whileループはi反復ごとに減少することに注意してください。このようにすると、はに評価されるi = 0ため、ループは終了します。while(0)false


アレイの「チャンキング」


チャンク()関数は、配列を小さなチャンク(したがって名前)で処理するように設計されており、3つの引数を受け入れます。項目 の「実行」リスト、 各項目を処理する関数、および値を設定するためのオプションのコンテキスト 変数です。 process()関数内でこれを実行します。各アイテムの処理を遅らせるためにタイマーが使用されます(この場合は100ミリ秒ですが、特定の用途に合わせて自由に変更してください)。通過するたびに、配列の最初の項目が削除され、process()関数に渡されます。処理するアイテムがまだ残っている場合は、別のタイマーを使用してプロセスを繰り返します

ブラウザがクラッシュする可能性を減らすためにセクションでループを実行する必要がある場合は、ここで定義されているNickZakasのメソッドを参照してください。chunk

function chunk(array, process, context){
    setTimeout(function(){
        var item = array.shift();
        process.call(context, item);

        if (array.length > 0){
            setTimeout(arguments.callee, 100);
        }
    }, 100);
} 

createDocumentFragment()の使用


ドキュメントフラグメントはメモリ内にあり、メインのDOMツリーの一部ではないため、子を追加してもページのリフロー(要素の位置とジオメトリの計算)は発生しません。その結果、ドキュメントフラグメントを使用すると、多くの場合、パフォーマンスが向上します。

DocumentFragmentは、Internet Explorer 6を含むすべてのブラウザーでサポートされているため、使用しない理由はありません。

リフローは、レイアウトエンジンのフォーマットオブジェクトのジオメトリが計算されるプロセスです。

これらの要素の表示プロパティを繰り返し変更しているため、ページは変更のたびにウィンドウを「再描画」します。そこですべての変更を使用createDocumentFragmentして行い、それらをDOMにプッシュすると、必要な量が大幅に削減されますrepainting

于 2012-10-19T19:03:26.620 に答える
0

また、約1500のアイテムをループしているときに、パフォーマンスの問題が発生します。

ご想像のとおり、ループ自体はボトルネックではありません。問題となるのは、その中で行う操作です。

したがって、setTimeoutを使用して負荷を移行したもの。最も美しいソリューションではありませんが、更新の合間にブラウザが応答するようになります。

var _timeout_ = 0;
for(var i=0;i < nodes.length; i++)
{
    setTimeout(
        (function(i)
        {
            return function()
            {
                if(stuff)
                {
                    nodes.get(i).style.display="block";
                }
                else
                {
                    nodes.get(i).style.display="none";
                }
            }
        })(i),
        _timeout_
    );
    _timeout_ += 4;
}

これにより、すべての更新が4ミリ秒遅れます。操作に時間がかかると、ブラウザが応答しなくなります。最も遅いブラウザでの操作に2ミリ秒しかかからない場合は、3に設定するなど、いろいろ試してみてください。

于 2012-11-15T09:22:39.507 に答える
0

まず、遅延はどこで発生していますか? jquery コードまたはデータ チェックで? jquery の場合は、DOM からデータ コンテナー要素 (つまり、すべての .rr div を含む html 要素) を切り離し、変更を加えてから、再度接続してみてください。これにより、変更のたびにブラウザーが DOM を再処理するのを停止します。

于 2012-10-19T19:06:08.257 に答える
0

私は試してみます

1) これらすべての div の共通の親要素の表示を「なし」に設定します

2) div をループし、必要に応じて表示を設定します

3) 親要素の表示をブロックに戻す

表示プロパティを変更するたびに完全に完了するように強制するのではなく、ブラウザにレンダリングの更新を集約する機会を与えるため、これが役立つと思います。親が表示されていない場合、すべての子ノードの可視性は無関係であるため、親が再び表示されるまで、ブラウザーは各子の変更をレンダリングする必要がなくなりました。

また、もう一度ループして意図した値に設定する前に、最初にそれらすべてをループしてすべてをブロックするように設定する目的がわかりません。

于 2012-10-19T19:06:46.207 に答える
0

ここで jQuery を使用しないでください。jQuery は処理を遅くするだけです。

    var elements = document.getElementsByClassName('rr'),
        len = elements.length;

    for(var i = 0; i < len; i++)
    {
        var ele = elements[i];
        if(ele.innerHTML.search(/01046/) != -1)
            ele.style.display = "none";
    }

これははるかに高速です。

于 2012-10-19T19:09:53.220 に答える