こんにちは!フロントエンドの現場を渡り歩いているチーフアーキテクトの私です。
Webサイトを作っていて、「なんだかスマホでスクロールするとカクつく」「ボタンを押してから画面が切り替わるまでに一瞬フリーズする」……そんな謎のプチストレスに直面したことはありませんか?
「コードはちゃんと書いたはずなのに、なぜ!?」と頭を抱えたくなるその現象、実はブラウザの「メインスレッド」が過労死寸前になっていることが原因かもしれません。
今回は、Webブラウザの頭脳である「メインスレッド」がなぜブロッキング(渋滞)を起こしてしまうのか、そしてどうやってそれを防ぐのかを、身近な例えを交えながら優しく紐解いていきましょう。
難しく考えなくて大丈夫です。一歩ずつ、一緒に見ていきましょう!
—
1. ブラウザの心臓部:「メインスレッド」ってなに?
Webブラウザが私たちの目の前にきれいなWebページを表示するまでの裏側を、お店に例えて考えてみましょう。
あなたがおいしいパンケーキ屋さんを営んでいるとします。このお店には、スタッフが「1人だけ」しかいません。その名も「メインスレッド君」です。
メインスレッド君は、一人で何役もこなす超多忙なスーパースターです。
- HTMLを読んで「ここに椅子を置いて、テーブルを並べて…」とお店のレイアウトを作る(DOM/CSSOMの構築)
- お客さん(ユーザー)がドアを開けて入ってきたら挨拶をする
- お客さんが注文したパンケーキを焼く(JavaScriptの実行)
- お皿やテーブルをピカピカに拭いて、見た目を整える(画面の再描画・レンダリング)
……どうですか?想像しただけで目が回りそうですよね。「一人でそこまでやるの!?」と驚くかもしれませんが、Webブラウザのタブ(画面)の基本は、このメインスレッド君がたった一人で切り盛りしているんです。
—
2. なぜ「重い処理」で画面が固まるのか?(ブロッキングの正体)
ある日、お店(ブラウザ)にこんな注文が入りました。
「すっごく複雑で、ものすごく時間がかかる巨大な数字の計算をして!」(重いJavaScriptの実行)
メインスレッド君は真面目なので、「かしこまりました!」と、その巨大な計算を一人で黙々と始めました。
ここで問題が発生します。
メインスレッド君は「一度に一つのことしかできない(シングルスレッド)」という性質を持っています。つまり、目の前の重い計算に集中しすぎてしまうと、他のお客さんの声が一切聞こえなくなってしまうのです。
これが、Webの世界でいう「メインスレッドのブロッキング(ブロック状態)」です。
- ユーザーが画面をスクロールしようとしても、反応しない。
- ボタンをクリックしても、何秒間かフリーズしたまま動かない。
- アニメーションがカクカクと途中で止まってしまう。
ユーザーからすれば、「あれっ、サイトが壊れた!?」と不安になってしまう瞬間ですね。メインスレッド君が一人でキャパオーバーになり、お店全体が麻痺してしまっている状態なのです。
—
3. 救世主登場!「Web Workers」で仕事を分担しよう
「じゃあ、スタッフをもう一人増やせばいいんだ!」
その通りです。ブラウザの世界にも、メインスレッド君を助けるための「裏方スタッフ」が存在します。それが「Web Workers(ウェブワーカー)」という仕組みです。
Web Workersを使うと、メインスレッドとは全く別の、裏側のバックグラウンド専用の部屋(別スレッド)を用意することができます。
先ほどのパンケーキ屋さんの例で言うと、こうなります。
- メインスレッド君(表の店員): 接客、画面の描画、簡単なクリックの反応など、「ユーザーに見える部分」を担当する。
- Web Worker君(裏方の職人): 画面には見えないけれど、時間のかかる巨大な計算や、重たいデータの処理を裏で黙々とこなす。
裏方スタッフ(Web Worker)が裏で重い計算をしてくれている間、表のメインスレッド君は余裕の表情で、お客さんとおしゃべりしたり(スムーズなスクロール)、綺麗なパンケーキを焼き続けたり(滑らかなアニメーション)することができます。
これぞ、私たちが目指す「ブロッキングのない、サクサク動くWebサイト」の裏側です!
—
4. 実践!Web Workersを使ってみよう
「なんだか難しそう……」と思いましたか?大丈夫です。基本的な使い方のイメージを見てみましょう。
今回は、重い計算(例として、すごく時間がかかる足し算のループとしましょう)を、裏方スタッフ(Worker)にお願いするコードを書いてみます。
ステップ1:裏方の仕事内容を書いたファイルを作る (`worker.js`)
まずは、裏方スタッフ専用のスクリプトファイルを用意します。ここでは、メインから送られてきたデータを受け取って、重い計算をする役割を持たせます。
// worker.js (裏方スタッフの部屋)
// メインスレッドからメッセージ(お手紙)が届いたときの処理
onmessage = function(e) {
console.log(‘裏方: メインから仕事を受け取りました!’, e.data);
let sum = 0;
// わざとすごく重いループ処理(何十億回も足し算する)
for (let i = 0; i < 2000000000; i++) {
sum += i;
}
// 計算が終わったら、メインスレッドに結果を返す!
postMessage(sum);
};
ステップ2:メインのファイルから裏方に仕事を頼む (`main.js`)
次に、普段私たちが動かしているメインのファイルから、裏方スタッフを呼び出して仕事を頼みます。
// main.js (表のメインスタッフ)
// 1. 裏方スタッフ(worker.js)を雇う!
const myWorker = new Worker(‘worker.js’);
// 2. 「重い計算をして!」と裏方にメッセージを送る
console.log(‘表: 重い計算を裏方に依頼します’);
myWorker.postMessage(‘スタート!’);
// 3. 裏方から「計算終わったよ!」と連絡が返ってきたときの処理
myWorker.onmessage = function(e) {
console.log(‘表: 計算結果を受け取りました! 結果は:’, e.data);
alert(‘計算が終わりました!(画面は固まってませんでしたよね?)’);
};
// 4. 裏方が計算している間も、こちらは自由に行動できる!
console.log(‘表: 裏方が計算中も、私は元気にスクロールやアニメーションを動かします!’);
このように、重い処理を `new Worker()` で別世界に追い出すだけで、メインスレッドの平和(サクサクした操作性)を綺麗に守ることができるのです。
—
5. さいごに:実務での注意点と心構え
ここまで読んでいただきありがとうございます!「Web Workersってすごく便利だな、明日から全部に使おう!」と思ったかもしれませんが、実務で使う際にはちょっとした注意点もあります。
それは、「裏方スタッフ(Web Worker)は、画面のHTML(DOM)に直接触ることができない」というルールです。
裏方スタッフは画面のパーツを見たり触ったりする権限を持っていません。あくまで「計算」や「データの整理」などのバックグラウンド処理の専門家です。そのため、裏方で計算した結果をメインスレッドに送り返して、画面の書き換えは必ずメインスレッド君にお願いする必要があります。
最初は少し窮屈に感じるかもしれませんが、「画面を触る人と、計算する人を分ける」というこの役割分担の考え方こそが、モダンなWebアプリケーションを支える極意なんです。
最初はエラーが出たり、ファイルのパス(場所)でつまずいたりすることもあるかもしれませんが、「あ、今メインスレッド君が忙しすぎてフリーズしてるな」とブラウザの呼吸を感じられるようになると、フロントエンド開発が何倍も楽しくなりますよ。
あなたのWeb制作ライフが、カクつきのないスムーズで快適なものになりますように。応援しています!

コメント