ホームページ > 記事 > ウェブフロントエンド > setTimeou スレッドメカニズムの簡単な分析
『ハイ パフォーマンス JavaScript』という本を読んでいるときに、次の文を目にしました:
このようにページの上部にスクリプトを配置すると、通常、ユーザーが操作できるようになるまでに、空白のページが表示されるなど、顕著な遅延が発生します。ページの読み取りや操作を開始することさえできます。
説明は次のとおりです:
スクリプトをヘッドに配置すると、通常は次のように大幅な遅延が発生します: ページを開いたときにページが空白になり、ユーザーは読むことができませんまたは何らかの方法で対話します。
私の理解は、js を head に配置すると、js の読み込みと実行によりページのレンダリングが遅れるということです。 jsを最後に配置すると、jsの読み込みや実行よりも先にページの描画が行われるため、jsのブロックの影響を受けずに最初にユーザーに提示することができます。
検証するために、次の実験が行われました:
<p>hello world</p><script type="text/javascript"> function f() { var t = +new Date(); //运行5秒 while(true) { if(+new Date() - t > 5) { break; } } } f(); // ①</script>
実験結果は興味深いものです: hello world は出てくるまでに 5 秒待機しました。
詳細な検証: 上記のスクリプト部分を js 外部リンクとして導入するか、動的にロードします。 5秒待っても結果は出ました。
これは、すべての js がロードされて実行された後にページのレンダリングが行われる必要があることを意味します。上の段落には誤りがあります。
これは、jsがDOM操作を含まない限り、先頭と末尾に配置しても同じ効果があるという意味ですか?もちろん違います。たとえば、html内に画像やその他のリソースがある場合、jsが先頭に配置されている場合、画像のダウンロードはjsの実行が完了するまで待ってから開始する必要があります。ただし、jsが末尾に配置されている場合、画像のダウンロードは js の実行をブロックしません。画像のダウンロードと js の実行を並行して実行できます。
これで問題は終わりですか?もちろんそうではありません。フロントエンドの作業の非常に重要な部分は、上記の JS を最適化する方法です。そこでsetTimeoutを考えました。
setTimeout は、js コードの実行を遅延させるために使用されます。これには、背後での js の実行がブロックされないという利点があります。したがって、setTimeout もページのレンダリングをブロックしないと思います。
オプション 1: 上記の①の部分を次のように置き換えます:
setTimeout(f,0);
その結果、hello world は出力されるまでに 5 秒待つ必要があります。ただし、注意して見ると、ブラウザーのタグにロード記号が表示されていないことがわかります。
推測を続けます。0 は小さすぎるため、ブラウザーは setTimeout の背後に JS コードがないことを検出し、すぐに setTimeout の内容、つまり f 関数を実行します。そこで時間を 100ms に変更します。
オプション 2: 上記の①の部分を次のように置き換えます:
setTimeout(f, 100);
その結果、Hello World が即座にポップアップ表示されます。ちょっと興奮。興味のある学生は、この時点で、クリティカル値があることがわかります (ブラウザごとにクリティカル値が異なります)。それ以外の場合は、hello world が即座にポップアップ表示されます。 、内部の機能が完了するとポップアップします。
すごいですね、なぜこんなことが起こるのでしょうか?この質問に答えるには、ブラウザのスレッド メカニズムを研究する必要があります。
ブラウザ内には少なくとも 2 つのスレッドがあることがわかっています。js を解析するスレッドとインターフェイスをレンダリングするスレッドです。ここでは、それらを仮に JS スレッドと UI スレッドと呼びます。
jsはDOMを操作できるため、これらの要素の属性を変更しながらインターフェースを描画すると(つまり、JSスレッドとUIスレッドが同時に実行されると)、描画スレッドの前後で取得した要素のデータが保持されてしまう可能性があります。一貫性がなくなる。したがって、予期しないレンダリング結果を防ぐために、ブラウザーは JS スレッドと UI スレッドがキュー内で同期的に実行されるように制御します。
上記の質問に戻りますが、setTimeout が実行されると、JS スレッドの実行の途中で新しいタイマー スレッドが開きます。JS スレッドが完了すると、すぐに setTimeout が実行を開始することがわかります。つまり、時間が上記の臨界値未満である場合)、UI スレッドの実行時間が長すぎることによって引き起こされる setTimeout の重大な遅延によって引き起こされる悪いエクスペリエンスを回避するために、ブラウザーは setTimeout の有効期限が切れるまで待機することを選択し、その後実行されます。中のjs。 setTimeout の有効期限が切れるまでに長い時間がかかることが判明した場合、時間の無駄を避けるために、ブラウザーはすぐに UI スレッドに切り替えることを選択します。
結論: setTimeout は、時間のかかる JS コードの処理に使用できますが、2 番目のパラメーターを小さすぎないように注意してください。小さすぎると、同じ空白のページが表示されます。すべてのブラウザで満足できる 100 ミリ秒程度が推奨されます。もちろん、IE と互換性がない場合は、setTimeout を放棄し、Web Workers を選択するのが良いでしょう。
HTML4 では、js によって作成されたプログラムはシングルスレッドであり、Web ワーカーは HTML5 の新機能であり、Web アプリケーションでバックグラウンド処理を実装するために使用されるテクノロジーです。この API を使用すると、バックグラウンドで実行されるスレッドを非常に簡単に作成できます:
var worker = new Worker('*.js');// 后台线程是不能访问页面或窗口对象的// 但可通过发送消息和接受消息与后台线程传递数据worker.onmessage = function (e) {}; worker.postMessage = function (e) {};
以上がsetTimeou スレッドメカニズムの簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。