動的コンテンツがもたらす描画コスト
DOMが変更されるたびに、ブラウザはスタイル再計算・レイアウト・ペイントを実行します。チャットフィード、株価ティッカー、無限スクロールリストなど、多くの動的ウィジェットを抱えるページでは、これらの再計算がドキュメント全体に波及し、カクつきやフレーム落ちの原因になります。
CSSの contain プロパティは、特定のサブツリーがページの他の部分から独立していることをブラウザに伝えます。これによりエンジンはグローバルな再計算をスキップし、その要素を隔離された島として扱えるようになります。
contain の値と意味
contain にはスペース区切りで複数のキーワードを指定できます。
| 値 | 効果 |
|---|---|
layout | 外部の要素がこのサブツリーのレイアウトに影響を与えず、逆もまた同様。新しい整形コンテキストを確立します。 |
paint | サブツリーは要素のボックスにクリップされます。子要素がボーダーボックス外に描画されることはなく、ペイント範囲が限定されます。 |
size | 要素のサイズは指定された width / height のみで決まり、子要素のサイズを無視します。仮想化コンテナに有効です。 |
style | counter-increment や引用符などスコープ可能なプロパティを閉じ込めます。使用頻度は低いです。 |
strict | layout paint size style のショートハンド。完全なコンテインメントを適用します。 |
content | layout 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+
content と strict キーワードはプロパティ自体がサポートされる環境であれば認識されます。
注意点
contain: sizeには明示的な寸法が必須。width/heightが未指定だと要素は幅0で描画されてしまいます。sizeを使うときは必ずサイズを定義してください。- コンテインメントは万能ではありません。 小さな要素に多用するとオーバーヘッドが増えます。更新頻度が高く独立したサブツリーに限定して適用しましょう。
contain: styleの出番は限定的。 counter-increment や list-item のマーカーをスコープしますが、CSS カスタムプロパティは隔離しません。
まとめ
CSS コンテインメントは、動的コンテンツを持つあらゆるページにおいて、低コストで高い効果が期待できる最適化手法です。ウィジェットや埋め込み要素に contain: content を適用し、プロファイリングで実際の改善を確認することから始めてみてください。

