Featured image of post CSSのcontainプロパティで描画リフロー領域を分離しページを軽量化するFeatured image of post CSSのcontainプロパティで描画リフロー領域を分離しページを軽量化する

CSSのcontainプロパティで描画リフロー領域を分離しページを軽量化する

CSSのcontainプロパティを使った描画パフォーマンス最適化を徹底解説。特定ウィジェットの要素変更がページ全体のレイアウト再計算やペイントを引き起こすのをブロックし、動的コンテンツを含むページの表示を劇的に軽量化する実践テクニックを紹介します。

動的コンテンツがもたらす描画コスト

DOMが変更されるたびに、ブラウザはスタイル再計算・レイアウト・ペイントを実行します。チャットフィード、株価ティッカー、無限スクロールリストなど、多くの動的ウィジェットを抱えるページでは、これらの再計算がドキュメント全体に波及し、カクつきやフレーム落ちの原因になります。

CSSの contain プロパティは、特定のサブツリーがページの他の部分から独立していることをブラウザに伝えます。これによりエンジンはグローバルな再計算をスキップし、その要素を隔離された島として扱えるようになります。

contain の値と意味

contain にはスペース区切りで複数のキーワードを指定できます。

効果
layout外部の要素がこのサブツリーのレイアウトに影響を与えず、逆もまた同様。新しい整形コンテキストを確立します。
paintサブツリーは要素のボックスにクリップされます。子要素がボーダーボックス外に描画されることはなく、ペイント範囲が限定されます。
size要素のサイズは指定された width / height のみで決まり、子要素のサイズを無視します。仮想化コンテナに有効です。
stylecounter-increment や引用符などスコープ可能なプロパティを閉じ込めます。使用頻度は低いです。
strictlayout paint size style のショートハンド。完全なコンテインメントを適用します。
contentlayout paint style のショートハンド。size を含まないので、子要素に応じたサイズ変更が可能です。

コンテインメントが描画を分離する仕組み

例えば、固定配置されたチャットウィジェットの top 値を変更すると、通常はルートまでレイアウト再計算が伝搬し、無関係なブランチにも影響します。

.chat-widget {
  contain: layout paint size;
  width: 320px;
  height: 480px;
}

contain: layout を指定すると、ブラウザはこのサブツリーがコンテナ外部にレイアウト変動を起こさないと判断し、Layout ステップをコンテナ境界で停止します。contain: paint は子のピクセルがコンテナのボーダーボックス外に漏れないようにし、再ペイント範囲を小さなダーティ領域に限定します。

実践的なユースケース

サードパーティ埋め込み — Twitter タイムラインや地図ウィジェットは予測不能な DOM 変更を伴います。それらを contain 指定した <div> でラップすることで、内部リフローがメインコンテンツに影響するのを防げます。

<div class="embed-container">
  <div id="third-party-widget"></div>
</div>
.embed-container {
  contain: content;
  width: 100%;
  max-width: 600px;
}

仮想スクロール — react-window などのライブラリはビューポートコンテナに明示的な寸法を設定します。contain: strict を追加するとサイズ契約が強化され、クリップされた子要素のペイント最適化が機能します。

アニメーション要素 — ローディングスピナーのような連続アニメーションはフレームごとに再ペイントを要します。コンテインメントでペイント範囲を隔離することで、ページ全体への影響を抑えられます。

パフォーマンスの実測

10,000 DOM ノードを持つページでのベンチマーク例:

シナリオスタイル再計算レイアウト時間
コンテインメントなし~12 ms~8 ms
contain: content~2 ms~1 ms
contain: strict~2 ms<1 ms

ウィジェット数が増えるほど効果は顕著になります。複雑なダッシュボードでは、フレーム処理時間が全体で30~50%削減されるケースもあります。

ブラウザサポート

contain はすべてのモダンブラウザで利用可能です:

  • Chrome 52+
  • Firefox 69+
  • Safari 15.4+
  • Edge 79+

contentstrict キーワードはプロパティ自体がサポートされる環境であれば認識されます。

注意点

  • contain: size には明示的な寸法が必須。 width / height が未指定だと要素は幅0で描画されてしまいます。size を使うときは必ずサイズを定義してください。
  • コンテインメントは万能ではありません。 小さな要素に多用するとオーバーヘッドが増えます。更新頻度が高く独立したサブツリーに限定して適用しましょう。
  • contain: style の出番は限定的。 counter-increment や list-item のマーカーをスコープしますが、CSS カスタムプロパティは隔離しません。

まとめ

CSS コンテインメントは、動的コンテンツを持つあらゆるページにおいて、低コストで高い効果が期待できる最適化手法です。ウィジェットや埋め込み要素に contain: content を適用し、プロファイリングで実際の改善を確認することから始めてみてください。