ブラウザーの描画経路:フレーム時間を段階別に調べる
DOMからコンポジットまでを固定手順ではなく診断モデルとして捉え、DevToolsの記録からレイアウト・ペイント・合成の負荷を見分けます。
発行・訂正窓口:infostoa · 編集基準
この記事の個別の執筆者・専門査読者の情報は提供されていません。
描画経路は診断モデルとして使う
ブラウザーはHTMLとCSSを解釈して画面を描きますが、毎回DOM → CSSOM → レンダーツリー → レイアウト → ペイント → コンポジットの一連の処理を最初から最後まで一度だけ実行するわけではありません。解析とリソース読み込みは並行することがあり、スクリプト・スタイル・画像の変更やユーザー操作に応じて、必要な計算だけが再実行される場合もあります。各段階の名称は、性能記録を読むためのモデルとして使うと実態に合います。
概略として、ブラウザーはDOMノードを作りスタイルを計算し、必要に応じてレイアウトの幾何情報を計算し、ペイント処理を記録してコンポジットします。display: noneはレイアウトボックスを作りませんが、visibility: hiddenは通常その空間を保ちます。スタイルシートの読み込みが初回描画に影響することはありますが、すべてのページがすべてのスタイルシートの取得完了まで常に全面白紙になる、という意味ではありません。文書構造、スクリプトの依存関係、ブラウザーの動作も関係します。
CSS変更で発生し得る処理
| 変更例 | 再計算される可能性がある処理 | 記録で確認する手掛かり |
|---|---|---|
| 幅や文字サイズを変更 | レイアウトと、その後のペイント・合成 | 長いLayoutやRecalculate Style、影響範囲 |
| 影や背景を変更 | ペイントと合成 | 長いPaintやラスタライズ処理 |
transformやopacityを変更 | 場合によってはレイヤー更新と合成のみ | ペイントが省略されたか、レイヤーやメモリー使用量が増えたか |
最後の行は保証ではありません。プロパティ、効果、レイヤー化、ブラウザー、端末によってペイントやラスタライズが必要になることがあり、GPUが使われるとも限りません。すべての要素にwill-changeを指定したり、何でもレイヤー化したりすると、メモリーや合成の負担が増える場合があります。
DevToolsで原因を絞る
- Chrome DevTools Performanceで操作を記録し、時間の長いフレームを選びます。この記録はそのブラウザー・端末・ページ実行での観測であり、他環境での保証ではありません。
- Mainトラックで
Recalculate Style、Layout、Paintにかかった時間を見ます。スタイル変更の直後にgetBoundingClientRect()やoffsetHeightを読むコードがあれば、同期レイアウトを強制していないか調べます。 - レイアウトが繰り返される場合は、同じループ内でDOM書き込みと寸法読み取りを交互に行わず、更新をまとめてから必要な寸法を読み、同条件でもう一度記録します。
- ペイント負荷が大きい場合は、影響範囲とCSS効果を確認します。
transformやopacityへの変更は、フレーム時間とレイヤーメモリーを比較し、対象端末で効果がある場合だけ採用します。
仮想例:カードを開くアニメーション
カードの開閉で毎フレームheightを変えると、周囲のコンテンツも繰り返しレイアウトされることがあります。固定領域内のtransform/opacity切り替えにすれば再配置を減らせる可能性がありますが、内容が隠れたりアクセシビリティ上の動作が変わったりするなら適切ではありません。これは起こり得る原因と実験方法を示す仮想例で、計測結果ではありません。上の手順で実際の記録を比較して判断します。
SSRと画像寸法は別々に検討する
サーバーサイドレンダリングは初期HTMLの到着時点やクライアントのハイドレーション時点を変えますが、LCPやINPを自動的に改善するわけではありません。応答時間、描画を妨げるリソース、クライアントスクリプト、コンテンツ構造を合わせて計測します。画像の固有寸法や縦横比を指定すると表示領域を先に確保でき、レイアウト移動の軽減に役立ちます。ただし画像のデコード、フォント切り替えなど、ほかの移動要因までは解消しません。
資料:MDN Critical rendering path、MDN How browsers work、Chrome DevTools Performance。