日本語版
最新ニュース
科学&テクノロジー

Web パフォーマンス カレンダー » ブラウザーのメイン スレッドを理解する

ブラウザは単一の メインスレッド 最も重要なタスクを実行するために、JavaScript の実行、ユーザー操作の処理、DOM の更新を担当します。メインスレッドはレイアウトと描画も実行します。 これらはブラウザの高レベルのタスクであり、 メインスレッドでは、ここで言う「メインスレッド」とは何でしょうか?それはどこから来たのでしょうか?そして、なぜ複数のスレッドを使用しないのでしょうか? 「メインスレッド」とは何ですか? メインスレッドは単一のスレッドです。 ほとんど ブラウザの作業のうち、これらのタスクには次のものが含まれます。 JavaScriptの実行 – JavaScript は本質的にシングルスレッドであり、デフォルトではメインスレッドで実行されます。 DOM の操作 – DOM で行われる更新はメインスレッドで行われます。 スタイルの再計算 – 要素のスタイルが変更されると、再計算されてメインスレッドに描画されます。 ユーザーインタラクション – ユーザーが画面上でスクロールしたり、ボタンをクリックしたり、タスクを実行したりすると、すべてメインスレッドで発生します。 なぜメインスレッドなのか?なぜマルチスレッドではないのでしょうか? ブラウザが 1 つのスレッドで非常に多くの処理を実行していると知ったとき、最初に思い浮かぶのは次のようなことです。 なぜ複数のスレッドを使用できないのでしょうか?今ではそれに対応できる強力なハードウェアがたくさんあるのでしょうか? 私も同じ質問をしましたが、ブラウザが依然として主要なタスクのほとんどを単一のスレッドで実行する理由は次のとおりです。 現在、最新のブラウザーはメイン スレッドをブロックしないバックグラウンド タスクである Web ワーカーを利用していますが、これらはユーザーの中断をあまり必要とせず、バックグラウンドで処理できるタスクに使用できます。他にも次のようなものがあります SharedArrayBufferこの問題の解決に役立つ…

Web パフォーマンス カレンダー » ブラウザーのメイン スレッドを理解する

1734734963
2024-12-20 09:53:00

ブラウザは単一の メインスレッド 最も重要なタスクを実行するために、JavaScript の実行、ユーザー操作の処理、DOM の更新を担当します。メインスレッドはレイアウトと描画も実行します。

これらはブラウザの高レベルのタスクであり、 メインスレッドでは、ここで言う「メインスレッド」とは何でしょうか?それはどこから来たのでしょうか?そして、なぜ複数のスレッドを使用しないのでしょうか?

「メインスレッド」とは何ですか?

メインスレッドは単一のスレッドです。 ほとんど ブラウザの作業のうち、これらのタスクには次のものが含まれます。

  • JavaScriptの実行 – JavaScript は本質的にシングルスレッドであり、デフォルトではメインスレッドで実行されます。
  • DOM の操作 – DOM で行われる更新はメインスレッドで行われます。
  • スタイルの再計算 – 要素のスタイルが変更されると、再計算されてメインスレッドに描画されます。
  • ユーザーインタラクション – ユーザーが画面上でスクロールしたり、ボタンをクリックしたり、タスクを実行したりすると、すべてメインスレッドで発生します。

なぜメインスレッドなのか?なぜマルチスレッドではないのでしょうか?

ブラウザが 1 つのスレッドで非常に多くの処理を実行していると知ったとき、最初に思い浮かぶのは次のようなことです。 なぜ複数のスレッドを使用できないのでしょうか?今ではそれに対応できる強力なハードウェアがたくさんあるのでしょうか? 私も同じ質問をしましたが、ブラウザが依然として主要なタスクのほとんどを単一のスレッドで実行する理由は次のとおりです。

現在、最新のブラウザーはメイン スレッドをブロックしないバックグラウンド タスクである Web ワーカーを利用していますが、これらはユーザーの中断をあまり必要とせず、バックグラウンドで処理できるタスクに使用できます。他にも次のようなものがあります SharedArrayBufferこの問題の解決に役立つ Atomics と WASM ですが、これらはこの投稿の範囲を超えているため、自分で調べることができます。

JavaScript のシングルスレッドの性質

JavaScript は Web の言語であり、誰もが知っているように、 シングルスレッド 本質的に、この言語は 90 年代後半に、(特に DOM で) 操作が難しく、多くのバグを引き起こす可能性がある競合状態やデッドロックなどの複雑さを回避するために、シンプルな言語になるように設計されました。

DOM は スレッドセーフではありません。これはツリーであり、階層構造を持っており、マルチスレッド形式での同期タスクは非常に複雑になる可能性があります (複数のロックとミューテックス)。シングルスレッド モデルでは、これらの処理がシンプルかつ予測可能になります。すべての更新が順番に行われるため、複雑な不整合が回避されます。

JavaScript がシングルスレッドの場合、非同期タスクはどのように処理されるのでしょうか?

JavaScript では次の概念が使用されます。 イベントループ 非同期タスクを処理し、ノンブロッキング動作を提供することで、シングルスレッドであるにもかかわらず、JavaScript がノンブロッキング方式で応答できるようになります。

イベントループとは何ですか?そして、JavaScript はどのように動作するのでしょうか?

ブラウザーのコンテキストで、物事が内部でどのように連携するかを見てみましょう。まず、JavaScript のイベント ループと、言語がすべてのタスクを管理する方法を理解する必要があります。

JavaScript がシングルスレッドである場合、その言語は一度に 1 つのことしか実行できないと結論付けるでしょう?しかし、それは真実ではありません!この言語は非同期タスクを処理でき、ノンブロッキング I/O 操作を提供してスムーズに実行できます。

それはどのように機能するのでしょうか?

以下の画像を見て、言語プロセスがどのように機能するかを分析してみましょう。

画像の抜粋 MDN

関数を呼び出すたびに、その関数はスタックにプッシュされ、JS はスタックに FILO (先入れ後出し) データ構造を使用します。

  • 先入れ: 関数が呼び出されると、その関数はスタックの一番上にプッシュされます。
  • ラストアウト: スタック上の最新の (最後に追加された) 関数が最初に実行されます。完了すると、スタックからポップされます。

以下は、撮影した写真をわかりやすくするための実際の視覚化です。 jsv9000:

スタックは関数の実行を処理し、 JS では、次のような非同期タスクを管理するために使用されます。 setTimeout、Promise、および I/O 操作。

JavaScript では、 タスクキュー そして マイクロタスクキュー これらの操作を可能にし、これらのキューにより、シングルスレッド JavaScript がノンブロッキング方式でタスクを実行できるようになります。

コールバックキュー

コールバックキューは FIFO (先入れ先出し) データ構造 (最初に入力されたものが最初に出力されます)、このキューは次のような操作を処理します。 setTimeoutsetInterval、DOM イベントなど。

イベント ループは、これらのタスクをキューからキューに移動します。 コールスタック スタックが空のとき。

マイクロタスクキュー

マイクロタスクキューもFIFOですが、 優先度が高い コールバック キューよりも、このキューは次のような操作を処理します。 Promise.then そして MutationObserver コールバック。

マイクロタスク キューは、コールバック キューに移る直前に実行されます。これは、このキュー内のタスクがコールバック キュー内のタスクよりも高い優先順位を取得することを意味します。

そして、 イベントループ これらのキューとスタックを調整して、JavaScript で見られるスムーズなノンブロッキングの性質を確保します。これをすべてまとめると、ステップバイステップでどのように動作するかを次に示します。

同期コードを実行します。

  • イベント ループは、コール スタック内のすべての同期コードを実行することによって開始されます。

マイクロタスク キューを確認します。

  • コール スタックが空になった後、イベント ループはマイクロタスク キューをチェックします。
  • マイクロタスク キューにタスクがある場合、それらのタスクはコール スタックに移動されて実行されます。

コールバック キューを処理します。

  • マイクロタスク キューが空になると、イベント ループはコールバック キューからのタスクを処理します。
  • これらのタスクはコール スタックに移動され、1 つずつ実行されます。

繰り返す:

  • このサイクルは無限に繰り返されるため、JavaScript は同期コードと非同期コードの両方をシームレスに処理できます。

これを説明するコード例を次に示します。

console.log("Start");

setTimeout(() => {
    console.log("Task 1 (Callback Queue)");
}, 0);

Promise.resolve().then(() => {
    console.log("Task 2 (Microtask Queue)");
});

console.log("End");

このコードを実行すると、次の出力が表示されます。

Start
End
Task 2 (Microtask Queue)
Task 1 (Callback Queue)

これで、イベント ループがどのように機能するか理解できました。ブラウザがメイン スレッドを使用してタスクを処理する方法を理解しましょう。

ブラウザがメインスレッドでどのように動作するか

かなりの量の作業が行われます メインスレッド、その一部には次のものが含まれます。

  • JavaScript の実行: 同期および非同期の JavaScript コードを実行します。
  • ユーザーインタラクションの処理: クリック、スクロール、キー押下などのイベントを処理します。
  • DOM の更新: スタイルとレイアウトを再計算し、画面上のペイントを更新します。
  • イベント ループの実行: タスクキュー、マイクロタスク、レンダリングの更新を調整します。

これらすべてのタスクはコストのかかる操作につながる可能性があるため、デバッグできるようにするにはそれぞれのタスクを注意深く調べる必要があります。

JavaScriptの実行

すべての同期および非同期 JavaScript コードはメイン スレッドで実行され、慎重に管理しないと (長時間実行されるループやタイムアウト)、メイン スレッドによる他の重要なタスクの実行がブロックされる可能性があります。

ユーザーインタラクションの処理

ユーザーがページ上のボタンをクリックするか、スクロールなどのアクションを実行すると、これらのイベントはすべてメインスレッドで処理され、ブラウザーはこれらの入力を取得して処理し、それらによって生成される副作用を処理するか、ユーザーに提供する必要があります。いくつかのフィードバック。

DOM の更新

ユーザー入力または一部の JS コードの一部によって要素が変更されると、ブラウザーはスタイルを再計算し、CSSOM を構築し、新しいスタイルをレイアウトして画面にペイントする必要があります。これもすべてメインスレッドで行われます。 。

イベントループの実行

そしてもちろん、キューのチェックと関数スタックの実行はすべてメインスレッドで行われ、これらは非同期操作または何らかの計算を行う同期コードである可能性があります。

ブラウザのメインスレッド


上記のすべてのタスクはメイン スレッドでかなりの時間とリソースを費やす可能性があり、ブラウザと言語の機能によって制限されるため、これらのタスクは慎重に実行し、重要なタスクのためのスペースを解放し、ブロックされないようにする必要があります。すぐに実行する必要があるタスク。

考えられるのは、 メインスレッド として 船の機関室ここでは、多くの重要なタスク (ナビゲーション、メンテナンス、発電など) が実行されます。の イベントループ のようなものです タスクマネージャー その部屋の中で、タスクが論理的かつ効率的な順序で処理されるようにします。

#Web #パフォーマンス #カレンダー #ブラウザーのメイン #スレッドを理解する

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。