無断転載を禁止します
1. 高価な計算の処理
おそらく、複雑な Javascript アプリケーションの開発で最も複雑な側面は、ユーザー インターフェイスのシングル スレッドの性質です。 Javascript がユーザー インタラクションを処理するときの最良の状況は応答が遅いことであり、最悪の状況は応答がなくなりブラウザがハングすることです (JavaScript が実行されると、ページ内のすべての更新操作が一時停止されます)。このため、すべての複雑な操作 (100 ミリ秒を超える計算) を管理可能なレベルまで削減することが不可欠です。さらに、スクリプトが少なくとも 5 秒間実行されても停止しない場合、一部のブラウザ (Firefox や Opera など) は、スクリプトが応答しないことをユーザーに警告するプロンプト ボックスを生成します。
これは明らかに望ましくなく、応答しないインターフェイスを生成するのは良くありません。ただし、大量のデータを処理する必要がある場合 (数千の DOM 要素の処理など)、これはほぼ確実に当てはまります。
このとき、特に便利なのがタイマーです。タイマーは Javascript コードの実行を効果的に一時停止できるため、ブラウザが実行中のコードをハングさせることを防ぐこともできます (個々のコードがブラウザをハングさせるほどではない限り)。これを念頭に置いて、通常の集中的なループ計算をノンブロッキング計算に組み込むことができます。このタイプの計算が必要な次の例を見てみましょう。
長時間実行されるタスク:
<テーブル><tbody></tbody></table>
// 通常の集中的な操作
var table = document.getElementsByTagName("tbody");
for ( var i = 0; i < 2000; i++ ) {
var tr = document.createElement("tr");
for ( var t = 0; t < 6; t++ ){
var td = document.createElement("td");
td.appendChild(document.createTextNode("" + t));
tr.appendChild(td);
}
テーブル.appendChild(tr);
}
}
この例では、合計 26,000 の DOM ノードを作成し、その数値をテーブルに入力します。これはコストがかかりすぎるため、ブラウザがハングし、通常のユーザー操作ができなくなる可能性があります。これにタイマーを導入すると、異なる、おそらくより良い結果が得られます。
タイマーを使用して、長時間実行されるタスクを分割します。
<テーブル><tbody></tbody></table>
var table = document.getElementsByTagName("tbody");
変数 i = 0、最大 = 1999;
setTimeout(function(){
for ( var step = i + 500; i < step; i++ ) {
var tr = document.createElement("tr");
for ( var t = 0; t < 6; t++ ){
var td = document.createElement("td");
td.appendChild(document.createTextNode("" + t));
tr.appendChild(td);
}
}
テーブル.appendChild(tr);
}
if ( i < max )
setTimeout( argument.callee, 0 );
}, 0);
修正された例では、集中的な計算を 4 つの部分に分割し、それぞれが 6500 個のノードを作成します。これらの計算がブラウザの通常のフローを中断することはほとんどありません。最悪のシナリオは、これらの数値がいつでも調整される可能性があることです (たとえば、各セルが 3500 個の DOM ノードを生成するように、数値を 250 ~ 500 の間で変化させる)。しかし、最も印象的なのは、新しい非同期システムに適応するためにコードをどのように変更したかです。要素の数値が正しく生成されることを確認するには、さらに作業を行う必要があります (ループは永久に終了しません)。コードは元のコードと非常によく似ています。コードフラグメント間の反復状態を維持するためにクロージャを使用していることに注意してください。クロージャがなければ、このコードは間違いなくより複雑になります。
このテクノロジーを使用すると、オリジナルと比較して明らかな変化があります。ブラウザーの長時間のハングは 4 回の視覚的なページ更新によって置き換えられます。ブラウザーはこれらのコード スニペットをできるだけ早く実行しようとしますが、タイマーの各ステップの後に DOM の変更 (大規模な更新など) もレンダリングします。ほとんどの場合、ユーザーはこの種の更新に気づきませんが、更新が行われることを覚えておくことが重要です。
このテクノロジーが特に私にとって有効な状況が 1 つあります。それは、大学生のスケジュールを計算するために私が構築したアプリケーションです。当初、アプリケーションは典型的な CGI でした (クライアントがサーバーと通信し、サーバーがスケジュールを計算してそれを返しました)。しかし、私はそれを変更し、すべてのスケジュール計算をクライアントに配置しました。これはスケジュール計算のビューです。
これらの計算は非常に高価です (正しい答えを見つけるには、何千もの順列をたどる必要があります)。この問題は、スケジュール計算を実際の単位に分割する (完了した部分でユーザー インターフェイスを更新する) ことで解決されます。最終的に、ユーザーは高速で応答性が高く、使いやすいユーザー インターフェイスを提供しました。
テクノロジーがどれほど役立つかに驚かれることはよくあります。テスト ボックスなど、長時間実行されるプログラムでよく使用されます (これについてはこの章の最後で説明します)。さらに重要なことは、このテクノロジーは、ユーザーに豊かなエクスペリエンスを提供しながら、ブラウザ環境の制限を回避することがいかに簡単であるかを示しています。