「なぜかカクつく」を卒業する。`will-change`でGPUを味方につける最適解
現場でフロントエンドをやっていると、たまに遭遇する「アニメーションがどうしても滑らかにならない」という悪夢。一生懸命CSSを調整しても、なぜかGPUがサボっているような、あの微細なカクつき。
この記事を読んでいる君なら、一度は`transform`や`opacity`を駆使して「合成レイヤー(Compositing Layer)」の力でGPUを叩き起こそうとした経験があるはずだ。今日は、その最終兵器である`will-change`プロパティについて、ブラウザの深淵を覗きながら「正しく、そして賢く」使いこなすための勘所を共有しようと思う。
—
ブラウザが「レイヤー」を生成する瞬間の裏側
まず、ブラウザがどうやって画面を描画しているか、その「苦労」を想像してみてほしい。
普段、ブラウザはHTMLをパースしてDOMを作り、CSSOMと合体させてレンダリングツリーを構築する。そして、レイアウト計算(リフロー)を行い、各要素をペイントする。ここまではCPUの仕事だ。
通常、この描画は「一つの大きなキャンバス」に対して行われる。しかし、DOMの一部がアニメーションで激しく動くと、ブラウザは毎回その大きなキャンバス全体を再描画しなきゃいけなくなる。これが重い。
そこでブラウザは、特定の要素を「別のレイヤー(テクスチャ)」として切り出し、GPUに丸投げする。これを「コンポジット(合成)」と呼ぶ。`will-change`は、「おい、これからこの要素は激しく動くぞ。今のうちに独立したレイヤーに切り分けてGPUに載せておけ」という、ブラウザへの強力な先制通知なんだ。
`will-change`は「魔法の薬」ではなく「劇薬」だ
ここで多くのエンジニアが陥る罠がある。「じゃあ全部の要素に`will-change: transform`を貼れば最強じゃん!」と考えることだ。
これは大間違いだ。レイヤーを生成するということは、VRAM(GPUメモリ)を消費するというコストを支払うことを意味する。調子に乗ってページ内のあらゆる要素に適用すれば、メモリを食いつぶし、逆にレンダリングエンジンをパンクさせる。最悪の場合、ブラウザがクラッシュするか、モバイル環境で描画が崩壊する。「良かれと思ってやったことが、全てを台無しにする」という、現場で最も恐ろしいパターンだ。
実践:賢い`will-change`の運用方法
`will-change`は、「必要な時にだけ適用し、終わったら即座に解放する」のが鉄則だ。CSSだけで完結させるなら、ホバー時や特定のクラスが付与された時に適用するのが定石となる。
推奨される実装例
以下は、モーダルが開く際のアニメーションを想定した、モダンな実装例だ。
.modal {
/
普段は何も指定しない。
GPUメモリを浪費させないための配慮。
/
will-change: auto;
transition: transform 0.3s ease;
transform: translateY(100%);
}
.modal.is-open {
/
表示される直前にプロパティを宣言。
これでブラウザは「ああ、この要素は変形するんだな」と予測し、
あらかじめレイヤーの準備を始める。
/
will-change: transform;
transform: translateY(0);
}
/
アニメーション終了後、ブラウザが自動的に最適化を解除してくれるよう、
JSでクラスを外すか、transitionendイベントを待って
will-changeを解除するようなライフサイクル管理が理想的だ。
/
チーフアーキテクトからのアドバイス:デバッグの極意
「今、本当にGPUレイヤーが生成されているか?」を確認したければ、Chrome DevToolsを使い倒そう。
1. `Cmd + Shift + P` (Windowsなら `Ctrl + Shift + P`) でコマンドメニューを開く。
2. 「Show Layers」と入力して実行する。
3. 画面がレイヤー構造で表示されるはずだ。ここで、意図した要素が単独のレイヤーとして切り出されているか、あるいは「無駄なレイヤーが乱立していないか」を確認できる。
もし、意図しない要素までレイヤー化されていたら、それは`will-change`の使いすぎか、あるいは`z-index`などの影響でブラウザが「重なり順を守るためにレイヤーを分けるしかない」と判断しているサインだ。
まとめ:道具としての矜持
`will-change`は、ブラウザという巨大な機械の「エンジンルーム」に直接介入するようなものだ。
- 「いつ」適用するか(ユーザーのアクション直前)
- 「どのプロパティ」を指定するか(transformやopacityなど、合成のみで完結するものに絞る)
- 「いつ」解除するか(アニメーション終了後)
この3点を意識するだけで、君が書くWebサイトのUIは、驚くほど滑らかになるはずだ。公式マニュアルには載っていないが、現場で生き残るための「ブラウザへの礼儀」だと思って、ぜひ日々の開発に取り入れてみてほしい。
もし何かわからないことや、もっと深い「ブラウザの機嫌の取り方」が知りたければ、いつでも聞きに来るといい。現場の最前線で、また会おう。

コメント