こんにちは!フロントエンドの世界へようこそ。日々のサイト制作や開発、本当にお疲れ様です。
Webサイトを作っていて、「アニメーションがなんだかガクガクするな…」とか、「スマホでスクロールしたときに一瞬表示が遅れる気がする…」と悩んだことはありませんか?
「CSSもちゃんと書いたし、JavaScriptが重いわけでもなさそうなのに、どうして?」
そんなときに鍵を握っているのが、今回ご紹介する「コンポジット(合成)」というブラウザの仕組みです。
難しそうな名前に身構えてしまうかもしれませんが、大丈夫ですよ。仕組みを紐解いていくと、実は私たちの身の回りにある「あるもの」とまったく同じ仕組みなんです。
今日は、ブラウザが画面を描き出す最後の魔法「コンポジット」について、現場の泥臭い裏話も交えながら、世界一優しく解きほぐしていきますね。一緒に楽しく学んでいきましょう!
—
そもそもブラウザはどうやって画面を描いているの?
コンポジットのお話に入る前に、ブラウザが1枚のWebページを表示するまでの「3つのステップ」をかるくおさらいしておきましょう。
ブラウザはおおまかに、以下のようなステップで画面を描いています。
1. リフロー(レイアウト):
「どこに、どの大きさで配置するか」を決める、いわば間取り図の作成です。
2. リペイント(ペイント):
「どんな色や角丸にするか」を決めて、実際に色を塗るペンキ塗りです。
3. コンポジット(合成):
バラバラに描いた「透明なシート(レイヤー)」を、正しい順番で重ね合わせて1枚の絵に合成する作業です。
今日フォーカスするのは、この最後の砦である「コンポジット」です。
—
コンポジットは「アニメのセル画」を重ねる作業
「コンポジット(合成)」を一番イメージしやすい例えは、昔ながらの「アニメのセル画」です。
アニメーションを作るとき、背景、キャラクター、手前にある障害物(木や建物など)を、すべて1枚の紙に描いていたらどうなるでしょうか?
キャラクターが右に1歩動くたびに、背景も建物もすべて描き直さなければいけなくなりますよね。これでは気が遠くなるような作業量になってしまいます。
そこでアニメの現場では、以下のように透明なシート(セル画)を分けて重ね合わせます。
- レイヤー1(一番下):動かない「背景」
- レイヤー2(真ん中):トコトコ歩く「キャラクター」
- レイヤー3(一番上):手前を通り過ぎる「落ち葉」
キャラクターが動くときは、「レイヤー2」のシートだけを少し横にずらして、上からカメラでパシャリと撮影すればいいのです。背景や落ち葉を描き直す必要は一切ありません。
これこそが、ブラウザが行っている「コンポジット(合成)」の正体です!
ブラウザも、ヘッダー、サイドバー、動くボタンなどを別々の「レイヤー(透明なシート)」に分けて描いておき、最後にそれを重ね合わせて画面を作っているのです。
—
なぜコンポジットは「圧倒的に速い」のか?
リフロー(配置決め)やリペイント(ペンキ塗り)は、実はブラウザにとってものすごくエネルギーを使う大変な作業です。要素が1ピクセル動くたびに、ページ全体の配置を計算し直して、ペンキを塗り直さなければいけないからです。
しかし、コンポジットは違います。
すでに描き終わったシートを「ずらすだけ」「重ねるだけ」なので、圧倒的に処理が軽いのです。
そして、ここで登場するのが「GPU(グラフィックス・プロセッシング・ユニット)」という強力な助っ人です。
CPUとGPUの頼もしいコンビネーション
ブラウザの裏側では、2つの頭脳が働いています。
- CPU(中央処理装置):
「頭脳明晰な1人の天才建築家」です。複雑な計算や、ページの構造を解析するのが得意ですが、単純作業を大量にこなすのは少し苦手です。リフローやリペイントの指示を出します。
- GPU(画像処理装置):
「単純作業が超得意な、何千人もの職人集団」です。計算は苦手ですが、「画像を重ね合わせる」「画像を拡大・縮小・移動する」といった並列処理を、一瞬で終わらせる驚異的なパワーを持っています。
コンポジットの段階になると、CPUは「よし、シートは全部描き上げたぞ。あとは重ね合わせるだけだ!」と、職人集団であるGPUに処理を丸投げ(これをGPU加速、GPUハーウェアアクセラレーションと呼びます)します。
GPUは重ね合わせのプロなので、スマホの画面でも60fps(1秒間に60回描画するなめらかな動き)を涼しい顔してキープできるのです。
—
実際に動かして体感してみよう!
では、どうやってブラウザに「これ、別レイヤー(セル画)にしてね!」と伝えるのでしょうか。
CSSには、ブラウザにレイヤー化を促すための特別なプロパティがあります。
実際にエディタに貼り付けてブラウザで確認できる、シンプルで滑らかなアニメーションのコードを用意しました。HTMLファイルを作成して、貼り付けて動かしてみてくださいね。
なぜ `transform` と `will-change` なの?
上記のコードで使っている `transform: translateY()` は、コンポジット(合成)だけで処理される代表的なプロパティです。要素の位置を「ずらす」だけなので、周りのレイアウトに一切影響を与えません。
また、`will-change: transform;` は、ブラウザに対して「この要素、もうすぐ動かすからあらかじめ専用のセル画(レイヤー)を用意しておいて!」と優しく耳打ちするプロパティです。これによって、アニメーションが始まる瞬間の「一瞬の引っかかり(カクつき)」を防ぐことができます。
—
現場のリアルな落とし穴:「レイヤーの作りすぎ」に注意!
ここまで読むと、「じゃあ、全部の要素に `will-change` をつけてレイヤーに分ければ、サイト全体が超爆速になるのでは!?」と思うかもしれません。
実は、ここにプロの現場でもよくある大きな罠(落とし穴)があります。
専用のレイヤー(セル画)を作るということは、それだけスマホやパソコンのメモリ(VRAM)を消費するということです。
もし、ページ内にある何百個もの要素をすべてレイヤーに分けてしまうと、メモリが不足してブラウザがクラッシュ(強制終了)したり、逆にスクロールがカクカクになってしまう「レイヤー爆発」という現象が起きてしまいます。
迷ったときの優しいルール
- 本当に動く、重要な要素だけに絞る:
アニメーションするボタン、ふわっと表示されるポップアップ(モーダル)、追従するヘッダーなど、「ここぞ!」という場所にだけ `will-change` を使いましょう。
- 使い終わったら片付ける:
CSSで常に指定するだけでなく、JavaScriptでアニメーションする直前に `will-change` を付与し、終わったら削除するという工夫も、大規模な開発ではよく使われます。
最初は「ちょっと動きがカクつくな」と感じたときに、お薬を処方するような感覚で、ピンポイントで使ってみるのがおすすめですよ。
—
まとめ:一歩ずつ、ブラウザと仲良くなろう
今日のポイントをギュッとまとめますね。
1. コンポジットは「重ね合わせ」:
バラバラの透明なレイヤー(セル画)を、最後に1枚に重ね合わせる処理。
2. GPUが主役:
画像の重ね合わせは、並列処理のプロである「GPU」が高速で行う。
3. `transform` を使おう:
位置を動かすときは、リフローを起こさない `transform` を使うと圧倒的に軽くなる。
4. レイヤーの作りすぎは禁物:
メモリを大切にするために、`will-change` は必要な場所にだけそっと添える。
ブラウザのレンダリングの仕組みは、一見すると難解な迷宮のように思えるかもしれません。でも、こうして「アニメのセル画」や「職人集団のGPU」といったイメージで捉えると、少し身近に感じられませんか?
もし一度に理解できなくても、まったく心配いりません。次にCSSでアニメーションを書くときに、「あ、今ブラウザの中で職人たちがシートを重ね合わせてるんだな」と、ふっと思い出してもらえるだけで大成功です。
あなたの作るWebサイトが、優しくなめらかに動くよう応援しています。何かにつまずいたら、いつでもこの基本に立ち返ってみてくださいね。大丈夫、一歩ずつ進んでいきましょう!

コメント