javascriptコードの運行を加速する——長時間の運行を避ける

4316 ワード

前のページでは、XHRオブジェクトの非同期の部分的な観点を議論しましたが、非同期はどのぐらいの時間で相互作用の問題を解決できますか?
長時間の運行の原因
javascriptはブラウザ環境で実行していますので、割り当てられたリソースの数は非常に限られています.デスクトッププログラムと違って、自分の欲しいメモリのサイズとCPUの時間を自由にコントロールできます.Javascriptは厳しく制限されています.スクリプトを長時間実行するにも一定の制約があります.コードが特定の時間制限を超えた場合、または実行されているステートメントの数が特定の制約を超えた場合、ブラウザはエラーメッセージボックスを起動し、実行を続けるかそれとも停止するかを問い合わせることができます.
このような状況が発生した理由は主に二つあります.長すぎたり深すぎたりする入れ子の関数呼び出しです.大量の反復処理を行った.
for(var i = 0, len = obj.length; i < len; i++){

     process(obj[i]);          

}    
上のコードは最も一般的な反復状況であり、反復回数は未定であり、同時にすべての反復は同期ブロッキングで行われ、すなわち前の反復処理が完了してから次の反復が行われる.
  • この反復は同期して行われるべきですか?データの処理が他のコードの運行に支障をきたす場合、答えは同期して行わなければなりません.
  • 反復は特定の順序で行わなければならないことがありますか?通常、反復されたデータセットは、固定された順序ではなく、つまり、順序コードの実行を狂わせる.
  • ブロック分け処理
    ある反復に出会うと、時間がかかり、上記の2点は非必須である.このサイクルを分割してみてもいい.つまり、ブロックのアレイを分割して、小さなブロックでアレイを処理してもいい.基本的な考え方は、処理する項目のためにQueを作成し、setTimeoutを使って次の処理するデータを取り出して処理し、次のsetTimeoutを設定して反復することである.
    function chunk(array, process, context){
    
        setTimeout(function(){
    
               var item = array.shift();     //       
    
               process.call(context, item);
    
               !!array.length && setTimeout(arguments.callee, 100); 
    
         }, 100);                            
    
    }
    arrayは処理するデータセットであり、processはデータを処理する関数であり、contextは実行するコンテキストである.時間間隔は100 msに設定されています.Javascriptプロセスはデータを処理するイベントの間でアイドルになる時間があります.もちろん、あなたの必要に応じてこの間隔を変更することができます.
    var data = [222,333,234,342,4536,5674,5634,2342,342,643,344,234,342,4536,5674,5634,2342,234,342,4536,5674,5634,2342];
    
    function print(item){
    
        var div = document.getElementById('div');
    
        div.innerHTML += item + "<br />";
    
    }
    
    function chunk(arr, process, context){
    
        setTimeout(function(){
    
            var item = arr.shift();
    
            process.call(context, item);
    
                    
    
            !!arr.length && setTimeout(arguments.callee, 100);
    
        }, 100);
    
    }
    
    chunk(data.concat(), print);
    注意してください.最後に呼び出した時に、伝達されるのは行列のコピーです.shift方法は元の配列を変えますので、もちろん元の配列の変化を気にしないと無視できます.
    優勢
    配列ブロックは、煩雑なプロジェクトを複数の小さい塊に分割し、キューごとに個別に実行し、小さいサイズごとに処理した後、ブラウザにその他の機会を与え、これによって長い間スクリプトを実行するエラーが発生しないようにする.ある関数の動作時間が200 ms以上のときは、ブロック分割方式で処理することが考えられます.
    その他
    また、ブラウザの中にはDOMの操作が非常に頻繁に行われているものもあります.もし変化が多すぎると、ブラウザが起動しやすくなります.例えば、resizeイベントは、ブラウザが変化すると、Oresizeイベントが連続的にトリガされ、頻繁に起動されることになります.このような場合は、ブロック分けバージョンを使用することができます.すなわち、連続した同期コードを分割して、実行関数の要求が一時停止された後に実行される.
    function throttle(method, context){
    
        clearTimeout(method.tId);
    
        method.tId = setTimeout(function(){
    
            method.call(context);
    
        }, 100);
    
    }
    タイマーのIDは、メソッドの属性tIdに格納されており、呼び出しごとに前のタイマーIDをクリアして、前の呼び出しが実行されるのを防ぐ.時間間隔は100 msに設定されています.つまり、100 ms以内に、何回呼び出しられても、一回だけ実行すると、前の余分な回数はクリアされます.
    window.onresize = function(){throttle(resizeFunc);};
    参照リンク:http://www.nczonline.net/blog/2009/06/05/speed-up-your-javascript-the-talk/