私は長い実行機能があります。大きな配列を繰り返し処理し、各ループ内で関数を実行します。ほとんどの部分についてどのようにjavascriptで長期実行機能を分割するが、パフォーマンスを維持する
longFunction : function(){
var self = this;
var data = self.data;
for(var i=0; len = data.length; i<len; i++){
self.smallFunction(i);
}
},
smallFunction : function(index){
// Do Stuff!
}
これは結構ですが、私は周りの1500かそこら以上のアレイを取り扱っておりますときに我々は、JavaScriptの実行警告メッセージが供給のポイントを得ます。
だから私はこれを解読する必要があります。私の最初の試みはそうのようなものです:
longFunction : function(index){
var self = this;
var data = self.data;
self.smallFunction(index);
if(data.slides[index+1){
setTimeout(function(){
self.longFunction(index+1);
},0);
}
else {
//WORK FINISHED
}
},
smallFunction : function(index){
// Do Stuff!
}
だからここに私はループを削除し、各反復そのインデックスを増加させ、自己の呼び出し機能を導入しています。メインのUIスレッドに制御を戻して、JavaScriptの実行警告メソッドを防ぐために、私はsetTimeout
を追加して、各繰り返しの後に更新する時間を許しました。問題は、この方法で実際の作業を完了させるには文字通り10倍の時間がかかることです。何が起きているかは、setTimeout
が0に設定されているにもかかわらず、実際には10msほど待っています。大規模なアレイでは非常に迅速に構築されます。 setTimeout
を削除して、longFunction
呼び出しを行うと、元のループ方法に匹敵するパフォーマンスが得られます。
私は別の解決策が必要ですが、これはループと同等のパフォーマンスを持ちますが、JavaScriptの実行警告は発生しません。残念ながら、この例ではwebWorkersは使用できません。
このプロセスで完全に反応するUIは必要ありません。数秒ごとにプログレスバーを更新するだけで十分です。
ループの塊に分割するのはオプションですか?私。一度に500回繰り返す、停止する、タイムアウトする、進行状況バーを更新する、次の500を実行するなど..
もっと良い点はありますか?
ANSWER:
唯一の解決策は、仕事をチャンクしているようです。それがある場合は、次のインデックスは、250によってdivisbleであれば、私はここでやっているすべてをチェックしている
longFunction : function(index){
var self = this;
var data = self.data;
self.smallFunction(index);
var nextindex = i+1;
if(data.slides[nextindex){
if(nextindex % 250 === 0){
setTimeout(function(){
self.longFunction(nextindex);
},0);
}
else {
self.longFunction(nextindex);
}
}
else {
//WORK FINISHED
}
},
smallFunction : function(index){
// Do Stuff!
}
:私はUIは、すべて250回の反復を更新できるようにしています私の自己の呼び出し元の関数に以下を追加することにより
メインUIスレッドを更新できるようにタイムアウトを使用します。そうでなければ、我々は直接それを直接呼び出す。問題が解決しました!
それはバックグラウンドで非同期的にそれを実行することは可能ですか?あなたがそれを行うことができない場合、はい、それを塊に分解してください。 – Patashu
あなたの機能は各項目に対して正確に何をしていますか?一度に複数のsetTimeoutを実行することによって、それらを並列化することができます。 – exebook
@Patashu - Webワーカーはまだすべてのブラウザで利用できるわけではありません...したがって、合理的な塊に侵入することは安全なアプローチのようです。 –