JavaScript運転速度を上げる循環編の翻訳文

2706 ワード

この文章は第一の原因をもう一度説明します.最後に,従来の循環構造を置き換える開発モードを与え,シナリオの暴走を完全に回避できる.
Speed up your JavaScript,Part 1原文:Nichollas C.Zakasは前回の投稿(翻訳文)で、各ブラウザがどのような状況でスクリプトを起動するのかについて言及しました.Internet Explorerにとっては、ブラウザが複数のステートメントを実行した場合、スクリプトの実行を停止します.他のブラウザは、スクリプトを継続的に実行すると、一定時間を超えたときにヒントが与えられます.これらのブラウザがコントロールできないシナリオを探知するなら、どうやってスクリプトをより速く実行させることができますか?警告を避けるために.シナリオの暴走は基本的に次の4つの原因があります.サイクルの中で多すぎる操作を実行しました.肥大化した関数が多すぎる再帰過多のDOMはこの招待状の中で呼び出して、私は重点を第一条に置いておきます.循環中の多すぎる操作です.サイクルの動作は同期して行われるので、サイクルを実行するのにかかる時間は完全にサイクルの回数に依存します.このため、ループ実行の時間が長くなり、ブラウザのロックにつながる場合があります.一つは循環体に多くの操作が含まれています.二つは循環の回数が多すぎます.どちらの場合もブラウザのロックを直接引き起こし、スクリプトの暴走を知らせるメッセージを表示することができます.この問題を解決するコツは次の二つの問題を使って各サイクルを評価することです.このサイクルは同期して実行しなければなりませんか?循環中のデータは順番に実行しなければなりませんか?二つの問題の答えが否定であれば、循環中の操作を分解することができます.鍵はコードの具体的な環境によって上の二つの問題の答えを確定することです.典型的なサイクルは次のようになり得る.
 
  
for(var i=0; i < items.length; i++){
process(items[i]);
}
このサイクルは一見大きな問題ではないですが、長く走るかどうかはサイクルの回数によって決まります.サイクルの直後に他のコードがない場合は、サイクルの結果に依存する必要があります.最初の問題に対する答えは「いいえ」です.また、循環は毎回一つの数値だけを処理し、前回の循環の結果には依存しないので、二つ目の問題に対する答えも同様に否定的であることが分かります.これは、ループが何らかの方法で分解され、ブラウザのロックにつながることなくスクリプトが暴走するというメッセージを表示することを意味する.
「Professional JavaScript、Second Edition」という本では、それらの実行回数が非常に大きい幻に対して、以下の方法で処理することを勧めます.
 
  
function chunk(array, process, context){
setTimeout(function(){
var item = array.shift();
process.call(context, item);
if (array.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}
chunk関数の用途は、一つの配列を小さいサイズに分割することです.三つのパラメータを伝えることができます.処理する配列オブジェクト、処理関数、および任意のコンテキスト変数は、プロcess関数に対応するthisオブジェクトを設定します.最初のtimerは動作間の遅延を処理するために使用されます(ここでは100ミリ秒に設定されています.実際の必要に応じて自分で修正できます).この関数を実行するたびに、配列の最初のオブジェクトを取り出し、プロシーズ関数に転送して操作します.プロシーズに未処理のオブジェクトがあると、もう一つのtimerが起動して、待ち時間を繰り返します.上記のループは、この関数を以下の方法で使用できます.
chunk;
ここでの行列はキューの形をとっています.また、ループの過程で毎回修正されます.配列の元の状態を変更する場合、ここでは2つの方法を紹介します.1つはconcat関数を通して伝達する前に現在の配列のコピーを作成します.
chunk;
もう一つの選択は、直接chunk()関数を変更し、直接関数内部で修正します.
 
  
function chunk(array, process, context){
var items = array.concat(); //clone the array
setTimeout(function(){
var item = items.shift();
process.call(context, item);
if (items.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}
この方法は1つのインデックスだけを保存するよりも安全です.配列の内容は次のタイマが有効になる前に変化する可能性があります.
ここで述べたchunk関数は,サイクル性能を最適化するための出発点にすぎない.必要に応じて絶えず改善して、もっと多くの機能を持たせることができます.たとえば、配列内のすべてのオブジェクトが処理された後、関数のコールバックが追加されます.このように関数を修正するかどうかに関わらず、これはJavaScriptのコード開発モードであり、配列の処理性能を最適化するのに役立ちます.また、そのスクリプトの暴走に対する警告を避けることができます.