欠陥があります。可能な限り低いポイントでコードを分離/分割するようにしてください。長期的には、ループの各反復を分離するだけで十分である可能性は低いと思います。
ただし、実際に行う必要があるのは、 UI キュー(またはUI スレッド)を更新するのに十分な余地を実装に与える非同期ランナウェイ タイマーをセットアップすることです。これは通常、(client)、(node.js)、(近日公開予定) などのメソッドを使用して行われます。setTimeout()
nextTick
setImmediate
たとえば、配列があり、各エントリを処理したいとしましょう
var data = new Array(10000).join( 'data-' ).split('-'); // create 10.000 entries
function process( elem ) {
// assume heavy operations
elem.charAt(1) + elem.charAt(2);
}
for(var i = 0, len = data.length; i < len; i++ ) {
process( data[i] );
}
このコードは、配列を反復処理してそのデータを処理する古典的なループです。また、100% の CPU 時間を消費するため、すべてのエントリを処理するのにかかる限り、ブラウザーのUI キューをブロックします (基本的に、ブラウザーの UI がフリーズして応答しなくなることを意味します)。
それを避けるために、次のような構成を作成できます。
var data = new Array(10000).join( 'data-' ).split('-'); // create 10.000 entries
function runAsync( data ) {
var start = Date.now();
do {
process( data.shift() );
} while( data.length && Date.now() - start > 100 );
if( data.length ) {
setTimeout( runAsync.bind( null, data ), 100 );
}
}
runAsync( data.concat() );
そこで何が起こるの ?
私たちが基本的に行っていることは次のとおりです。
- 配列を取得し、 100 ミリ秒の時間枠内でできるだけ多くのデータ/エントリを処理します
- その後、処理を停止し ( を呼び出します
setTimeout
)、UI に更新の機会を与えます
- 配列にまだデータがある限り、それを行います
100 ミリ秒を超える遅延は、通常、人間の目によって「遅延」として認識されます。それ以下は流暢で素敵に見えます (少なくとも私たちの目はそう教えてくれます)。100ms は、最大処理時間の制限として適切な値です。50ミリ秒まで下げることをお勧めします。
ここでの注意点は、全体の処理時間が長くなるということですが、処理が速くなり、ユーザーエクスペリエンスが非常に悪くなる代わりに、処理を長くして応答性を維持する方が良いと思います.
クイックデモ: