ブラウザという「魔法の箱」の裏側で、一体何が起きているのか。
Web開発を始めたばかりの頃、誰もが一度は「なぜコードを書いた順番通りに動かないことがあるのか?」と首を傾げる瞬間があるはずです。
今日は、ブラウザの心臓部である「メインスレッド」という名の料理人について、少しだけお話しさせてください。この仕組みを理解すると、あなたの書くコードは、単なる命令文から、ブラウザという最高のパートナーへの「的確なリクエスト」に変わります。
—
メインスレッドは「たった一人」の料理人
ブラウザのメインスレッドをイメージしてみてください。これは、「小さなお店を一人で切り盛りする、超優秀なシェフ」です。
彼は、HTMLを読み込み、JavaScriptを実行し、画面を描画するという、すべての工程を一人でこなしています。彼には「一度に一つのことしかできない」という鉄の掟があります。だからこそ、彼を忙殺させないための「注文のルール」が非常に重要になってくるのです。
ブラウザの「注文票」:2つのキュー
シェフ(メインスレッド)の手元には、常に2つの注文票(キュー)が置かれています。
1. タスクキュー(マクロタスク):
「お急ぎの注文」です。`setTimeout`の実行や、クリックイベント、サーバーからのデータ受信など。シェフは一つずつ、丁寧に片付けていきます。
2. マイクロタスクキュー:
「超優先事項」です。主に`Promise`の完了処理など。「タスクの合間に、これだけは先にやっといて!」と割り込む、非常に優先度の高い仕事です。
—
処理の黄金ルール:「マイクロタスクは終わるまで帰さない」
ここが一番のつまずきポイントです。シェフがタスクを一つ処理するたびに、必ず以下のチェックが入ります。
1. タスクを一つこなす
2. マイクロタスクキューの中身を「空になるまで」すべて処理する
3. 画面の更新(レンダリング)が必要なら行う
4. 次のタスクへ!
つまり、マイクロタスクを大量に詰め込むと、シェフはいつまで経っても次の仕事や画面更新に移れず、ブラウザが固まったように見えてしまうのです。これが「重い処理で画面がフリーズする」の正体です。
—
実験してみよう:優先順位のリアル
実際に、コードがどういう順番で実行されるか見てみましょう。以下のコードをブラウザのコンソールに貼り付けてみてください。
console.log(“1. 最初の注文が入りました!”);
// タスクキュー(お急ぎ便)へ
setTimeout(() => {
console.log(“2. setTimeout(タスクキュー)が実行されました”);
}, 0);
// マイクロタスクキュー(超優先便)へ
Promise.resolve().then(() => {
console.log(“3. Promise(マイクロタスク)が割り込みました!”);
});
console.log(“4. 最初の処理が終わりました!”);
実行結果の予想:
1. `1. 最初の注文が入りました!`
2. `4. 最初の処理が終わりました!`
3. `3. Promise(マイクロタスク)が割り込みました!`
4. `2. setTimeout(タスクキュー)が実行されました`
……どうでしょう? `setTimeout`で0秒を指定したのに、`Promise`の方が先に実行されましたよね。これが、ブラウザの中の「優先順位」のリアルです。
—
焦らなくて大丈夫。少しずつ理解すればいい
ここまで読んで「うわ、複雑だな」と感じた方もいるかもしれません。でも、安心してください。伝説的なエンジニアたちも、最初は皆、この見えないタスクの流れに翻弄されてきました。
- 画面が固まる? → シェフに一気に重い仕事をさせすぎていませんか?
- 動くはずのタイミングで動かない? → マイクロタスクが渋滞していませんか?
そうやって、ブラウザの「中の人」であるシェフの気持ちになって考えてあげると、コードの書き方は劇的に変わります。
最初は完璧に理解できなくても大丈夫です。「あ、今このコードはタスクキューに並んだんだな」「今はマイクロタスクが割り込んでいるんだな」と、頭の中でシェフの動きをイメージする癖をつけるだけで、あなたはもう「ブラウザの仕組みを知る開発者」の第一歩を踏み出しています。
Webの世界は、少しずつ知ることで、どんどん面白くなっていきます。またいつでも、この「魔法の箱」の裏側を覗きに来てくださいね。

コメント