【入門編】 コンポジタースレッドの役割とタスク – Webブラウザの仕組み実践ガイド

こんにちは!フロントエンドの現場を渡り歩いているチーフアーキテクトです。

Webサイトを作っていて、「よし、きれいなページができた!」とブラウザで表示させてみたはいいものの、なんだかスクロールがカクカクしたり、CSSアニメーションが引っかかるように動いたりして、モヤッとした経験はありませんか?

「自分のコードの書き方が悪いのかな……」と不安になるかもしれませんが、大丈夫ですよ!そのカクカク、あなたのせいだけではありません。犯人は、Webブラウザのなかで日々、一人で大量の仕事を抱えててんてこ舞いになっている「メインスレッド」という頑張り屋の存在です。

今回は、このメインスレッドを助けるために裏でこっそり大活躍している、もう一つの主役「コンポジタースレッド」の秘密に迫ります。難しい専門用語は身近な例えに置き換えて優しくほどいていくので、ぜひ肩の力を抜いて読んでいってくださいね。

—

1. なぜブラウザはカクカクしてしまうのか?(メインスレッドの悲鳴)

まず、私たちが普段見ているWebページが画面に映し出されるまでの裏側を、少しだけ覗いてみましょう。

ブラウザの「メインスレッド」は、いわば「超多忙なレストランのワンオペ店長」のようなものです。
彼(メインスレッド)は、以下のような仕事をたった一人でこなしています。

1. HTMLやCSSを読み込んでパースする(注文票を解読して料理のレシピを作る)
2. JavaScriptを実行する(お客様の注文を聞いて、細かなオーダーや追加調理をする)
3. DOMやCSSOMのツリーを構築し、レイアウトを計算する(お皿の配置やテーブルのレイアウトを考える)

ここに、ユーザーが「スクロール」をしたり、「アニメーションする要素」をマウスで動かしたりするアクションが加わります。
もし、このワンオペ店長(メインスレッド)が重たいJavaScriptの計算などで手一杯になっているときに、スクロールの処理まで「店長、次のスクロール位置を計算してください!」と頼んでしまったらどうなるでしょう?

店長はパニックを起こし、「ちょっと待って!今それどころじゃないから!」と手が止まってしまいます。これが、画面がカクつく(フレームレートが落ちる)正体です。

—

2. 救世主登場!「コンポジタースレッド」とは何か?

「これじゃあユーザー体験が最悪だ!」ということで、近代のWebブラウザに搭載された強力な仕組みが「コンポジタースレッド(Compositor Thread)」です。

彼を例えるなら、「優秀なアルバイトのサブマネージャー」です。
メインスレッド(店長)が裏で重たいJavaScriptやレイアウトの計算に追われているとき、コンポジタースレッド(サブマネージャー)は、「スクロール」や「簡単なアニメーション」といった、メインスレッドを巻き込まずに済む仕事をごっそり引き受けてくれます。

コンポジタースレッドの最大の特徴は、メインスレッドとは完全に独立した別の部屋(スレッド)で動いているという点です。
だから、たとえメインスレッドがJavaScriptの計算でウンウン唸ってフリーズ気味だったとしても、コンポジタースレッドは平然と「お、ユーザーがスクロールしたな。画面をスルスルっと動かそう」と、スムーズに画面を動かし続けることができるのです。

—

3. コンポジタースレッドがGPUへ命令を送るまでの流れ

では、コンポジタースレッドは具体的に裏でどんな魔法を使っているのでしょうか? ざっくりとした流れを見てみましょう。

1. レイヤー(層)に切り分ける
ブラウザはWebページを、まるで透明なフィルムを何枚も重ね合わせたような「レイヤー(層)」構造に分解します。
2. ペイント(描画)の準備
それぞれのレイヤーに何が描かれているかの「絵の具の塗り方(ドロー)」をあらかじめ用意しておきます。
3. コンポジット(合成)とGPUへのパス
ここからがコンポジタースレッドの真骨頂です。コンポジタースレッドは、これらのレイヤーを「どの位置に、どう重ねるか」を計算し、直接パソコンのグラフィックボード(GPU)に「このレイヤーをこっちに動かして!」と命令を送ります。

GPUは画像や映像の処理のプロフェッショナルです。GPUに直接お仕事をお願いすることで、CPU(メインスレッド)を一切わずらわせることなく、驚くほど滑らかな60fps(あるいはそれ以上)の動きを実現しているのです。

—

4. 実務で使える!コンポジタースレッドを味方につける魔法のCSS

「なるほど、コンポジタースレッドがすごいのはわかったけど、私たちWeb制作者はどうすれば彼を助けられるの?」

ここで、今日からすぐに使える実用的なテクニックをご紹介します。
コンポジタースレッドに「お、この部分は俺(コンポジター)だけで動かせるな!」と気づいてもらうためには、ブラウザに対して「この要素は独立したレイヤーにしますよ」とヒントをあげることが大切です。

その代表格が、CSSの `transform` や `opacity` です。

❌ メインスレッドを疲れさせてしまう書き方(例)

要素の位置を変えるときに `top` や `left`、あるいは幅を変える `width` などをいじっていませんか?
これらは、ブラウザに「レイアウトの再計算(Reflow)」を強要するため、メインスレッドが呼び出されてしまいます。

/ メインスレッドが頑張りすぎてカクつきやすい例 /
.box {
position: absolute;
top: 0px; / topやleftを変更するとレイアウトから計算し直すので重い! /
transition: top 0.3s ease;
}

.box:hover {
top: 50px;
}

⭕ コンポジタースレッドが大活躍する書き方(例)

代わりに、要素の「位置の移動」や「拡大縮小・回転」には `transform` を使い、「透明度の変更」には `opacity` を使ってみてください。
これらは、メインスレッドを通さず、コンポジタースレッドとGPUだけで処理(合成=Compositing)が完結するため、驚くほど滑らかに動きます。

/ コンポジタースレッドとGPUが爆速で処理してくれる例 /
.box {
transform: translateY(0); / 位置の移動は transform を使うのが現代の鉄則 /
transition: transform 0.3s ease;
}

.box:hover {
transform: translateY(50px); / メインスレッドを呼ばずにGPUだけでスルスル動く! /
}

さらに、「どうしても特別なレイヤーとして事前に切り分けておきたい!」という強力なプロパティとして `will-change` や `transform: translateZ(0)` というハックもあります。

.heavy-animation-element {
/ ブラウザに「この要素はこれからアニメーションするから、専用のレイヤーを作っておいてね!」と事前に伝える /
will-change: transform, opacity;
}

(※注意:`will-change` は便利だからといってページ中のあらゆる要素に貼り付けると、逆にメモリを食いつぶしてしまうので、「ここぞ!」という重たいアニメーションの要素だけに優しく使ってあげてくださいね)

—

おわりに

いかがでしたでしょうか?
普段私たちが当たり前のようにスワイプしたり、滑らかに動かしたりしているWebページの裏側では、「メインスレッド」という頑固で忙しい店長と、「コンポジタースレッド」という優秀なアルバイトが、見事なチームワークでブラウザを支え合っています。

「なぜこの書き方だとサクサク動くのか」「なぜあの書き方だとカクつくのか」。
その理由がブラウザの内部構造(スレッドの仕組み)まで分かってくると、コードを書くのがもっと楽しく、愛おしくなってきますよね。

あなたの書いたコードが、コンポジタースレッドにバトンをうまく渡し、ユーザーの画面で最高に気持ちよく動きますように。
それでは、また次のフロントエンドの旅でお会いしましょう!

コメント

タイトルとURLをコピーしました