CSSのレンダリングの仕組みとGPUアクセラレーションの注意点

以前のブログはこちら

広告

こんにちは。ましじめの田村です。

私が執筆した著書、『現場のプロから学ぶ CSSコーディングバイブル』は、Web制作の現場で役立つテクニックやノウハウをまとめています。
興味を持っていただけた方は、ぜひご覧ください。
https://amzn.to/3A8kNHC

このリンクは Amazon のアフィリエイトプログラムを通じて設定されています。

こんにちは。田村です。
今回は「CSSアニメーションをより滑らかに動かすポイント」について、レンダリングの仕組みとGPUアクセラレーションの注意点を交えながらまとめてみました。
Webサイトでアニメーションを取り入れる場合、プロパティの選び方やGPUの活用次第でパフォーマンスが大きく変わります。
それでは早速、ブラウザのレンダリング工程から見ていきましょう。

CSSレンダリングの概要

ざっくりレンダリングの流れ

ブラウザは、HTML/CSS/JavaScriptを解析してまず DOMツリー と CSSOMツリー を生成します。
その後、この2つを合体させた Render Tree を作り、以下の手順で画面に描画します。

Rendering(レンダリング)

Layout(レイアウト)
各要素の大きさや位置を計算する工程。一般的に「リフロー」とも呼ばれます。

Painting​(ペインティング)

Paint(ペイント)
テキストや背景色、ボーダー、画像などを ピクセル情報 として実際に塗りつぶす工程。
Composite Layer (コンポジットレイヤー)
レイヤーごとにGPUで合成し、最終的な見た目を描画する工程。

アニメーションを滑らかにする際に重要なのは、GPUアクセラレーションは主にComposite Layerで働くということです。
要素をうまく使うと、レイアウトの再計算(リフロー)を発生させずにCompositeだけでアニメーションできるため、滑らかな動作が期待できます。

GPUアクセラレーションが働く代表的なプロパティ

  • will-changeプロパティの使用
  • transformの3D変換
  • opacityの変更
  • position: fixedの要素

transform

transform: translate(), scale(), rotate(), skew() などは、Layoutに影響しない ため、要素の大きさ・位置、レイアウトの再計算(リフロー)を必要としません。

opacity

opacityの変更は、レイアウト計算(幅や高さの再計算)には影響しないため、通常はLayoutやPaintを変えずにComposite Layerだけで変化を適用できます。
そのため、opacityのフェードアニメーションは比較的スムーズに動作します。

ただし、opacity は背景や重なり合いが複雑な場合paint処理が増える場合もあるので、必ずしも高速とは限りません。

CPUレンダリングとGPUレンダリングの違い

CPU側での処理
top や left, width, height などのプロパティをアニメーションさせると、毎フレームごとにレイアウトの再計算(リフロー)が発生します。
複数要素で同時にこうしたアニメーションを使うとCPUに大きな負担がかかり、カクつきの原因になります。

GPU側での処理
GPUは 2D/3Dの描画や合成 に特化しており、並列処理が得意です。
transform や opacity でアニメーションする場合は、新たなレイアウト計算をせずにComposite Layerのみで見た目を更新できるため、フレームレート(60fps)を維持しやすいというメリットがあります。


任意でGPUアクセラレーションを引き出す方法

will-changeプロパティ
ブラウザに「もうすぐこのプロパティが変化するぞ」と知らせることができるので、あらかじめ最適化しておいてくれます。
ですが、ブラウザはすでに可能な限りすべての最適化を試みていますので指定しすぎると不要なレイヤーが生成されるため、使用には注意が必要です。

.element {
  will-change: transform, opacity;
}

GPU処理に良いケース

複数要素を同時にアニメーションさせる場合
画像ギャラリーが横に大量に流れるサイトなどは、レイアウトの再計算(リフロー)を最小限に抑え、滑らかな移動がしやすい。

スクロール連動やドラッグ移動など、ユーザー操作が頻繁に行われるUI
リアルタイムで要素位置が変化する場合に効果を発揮しやすい。

端末の性能が低い、またはFPSを確保したい場面
スマートフォンやタブレットなどCPUリソースが限られる環境で、GPUをフル活用することでカクつきを低減できる。

GPU処理の注意点

レイヤーが増えすぎた場合
レイヤーが増えすぎるとGPUのメモリ消費が増大し、合成コストもかさんで逆効果になる場合がある。

レイアウト変更時
transform や opacity はあくまで見た目を変えるプロパティなので、要素の実際の位置・高さを変えたい場合はレイアウトの再計算(リフロー)が発生する。

ブラウザ依存
古い端末や特定ブラウザではGPUの最適化が効きにくい。

メインスレッドの負荷は別問題
JavaScriptが重い処理を実行していれば、アニメーションの更新タイミング自体が遅れ、カクつきが発生することもある。

実測・検証方法

最終的には実際に パフォーマンス計測 してみることが大切です。

Chrome DevToolsのレンダリングを活用する


まとめ

transform や opacity を中心にアニメーションを組み立て、なるべくレイアウトの再計算(リフロー)を防ぎ、GPUアクセラレーションを効かせるのが、CSSアニメーションを滑らかに動かすポイントです。
やみくもにwill-changeを使うとレイヤーが乱立し、逆効果になることもありますので、Chrome DevToolsで実際に計測し、Paint/Compositeをチェックしながら、GPU処理が必要な箇所に使用すると良いでしょう。
より滑らかなアニメーションを実装してみてください!

告知


2025年1月31日(金)21:00~29:00 開催の「#朝までマークアップ 2(CSS編)」に出演いたします。
当日は、CSS アニメーションに関するお話をします。この記事にご興味を持っていただけましたら、ぜひご参加ください!



関連するタグ

全 1 件中 1 〜 1 件目を表示

この記事を書いた人

たむら しょうご

HTML&CSSコーダー

ウェブアクセシビリティ対応、フロントエンド開発、CMSを利用したウェブサイト制作を担当しています。
趣味はガーデニングです。

ましじめのスキルが必要ですか?

遠慮なくご相談ください。我々はあなたのプロジェクトに最善を尽くし、あなたのウェブサイトの制作を強力にサポートいたします。

お問い合わせはこちらから