CSS Containmentの仕組みを理解してレンダリングパフォーマンスをアップする3 検証
UI開発者 佐竹contain
プロパティにlayout
やpaint
を指定した場合やcontent-visibility
プロパティを設定した場合のCSS Containmentの検証をご紹介します。
これまでの関連Blogについては「CSS Containmentの仕組みを理解してレンダリングパフォーマンスをアップする1 概要」「CSS Containmentの仕組みを理解してレンダリングパフォーマンスをアップする2 検証」でご確認いただけます。
layoutの検証
contain: layout;
の設定の有無による要素の配置の違いからLayoutの封じ込めを検証します。
containプロパティがない場合
contain
プロパティの設定がないブロックを用意します。- ブロック内に3つの要素を設置します。
- 1つ目の要素は、
position: fixed;
を設定して相対的な配置にします。 - 2つ目の要素は、
float: right;
を設定して右側にフロートさせます。 - 3つ目の要素は、
position
やfloat
の設定、clear
のようなフロート解除の設定はしません。
- 1つ目の要素は、
- クリックするたびに、ブロック内のfixed要素が移動するボタンを用意します。
See the Pen layoutの検証(containプロパティがない場合) by ミツエーリンクス (@mitsue-links) on CodePen.
- 初期表示
- fixed要素はビューポートを基準とした相対配置になります。
- float要素はブロック要素の右側にフロートし、弟要素のテキストが左側に回り込みます。
- フロートは解除されません。
- ボタンをクリックして、fixed要素を移動
- fixed要素はビューポートを基準とした相対位置で移動します。
containプロパティにlayoutを指定した場合
ブロック要素にcontain: layout;
を指定して、包含ブロックとします。
See the Pen layoutの検証(containプロパティにlayoutを指定した場合) by ミツエーリンクス (@mitsue-links) on CodePen.
- 初期表示
- fixed要素は包含ブロック要素を基準とした相対配置になります。
- float要素は包含ブロック要素の右側にフロートし、弟要素のテキストが左側に回り込みます。
- 包含ブロックでフロートが解除されます。
- ボタンをクリックして、fixed要素を移動
- fixed要素は包含ブロック要素を基準とした相対位置で移動します。
- fixed要素は包含ブロックのパッディングの縁を超えても表示されます。
要素の配置の基準がビューポートではなく包含ブロックになっていることがわかります。 また包含ブロックでフロートが解除されることで、包含ブロック内のfloat要素が包含ブロック外に影響していません。
paintの検証
contain: paint;
の設定の有無による要素の描画の違いからPaintの封じ込めを検証します。
contain
プロパティがない場合の検証はlayoutを指定した場合のcontainプロパティがない場合と同じですので割愛します。
containプロパティにpaintを指定した場合
ブロック要素にcontain: paint;
を指定して、包含ブロックとします。
See the Pen paintの検証(containプロパティにpaintを指定) by ミツエーリンクス (@mitsue-links) on CodePen.
- 初期表示時
contain
プロパティにlayout
を指定した場合と同じ見た目になります。
- ボタンをクリックして、fixed要素を移動
- fixed要素は包含ブロック要素を基準とした相対位置で移動します。
- fixed要素は包含ブロックのパッディングの縁を超えると、はみ出た部分が切り取られたように描画されます。
包含ブロック内の要素を包含ブロックのpadding
領域の外側に配置すると表示されません。
そのため包含ブロックをオフスクリーンの位置に配置した場合は、包含ブロック内の要素も表示されません。
content-visibilityの検証
content-visibility
プロパティの設定による封じ込めを検証します。
仕組みを理解するところから少し踏み込んで、content-visibility
プロパティはauto
を指定することでcontain
プロパティと同じように封じ込めを有効にする他、hidden
を指定することで要素のレンダリングがスキップされるため、その場合のタブ遷移によるフォーカスやスクリーンリーダーでの読み上げなどのアクセシビリティへの影響がどうなるかを確認してみます。
ブロックを2つ用意します。
- 1つ目ブロック要素には
content-visibility: auto;
を設定し、ブロック内に3つの要素を設置します。- 1つ目の要素は、
position: fixed;
を設定して相対的な配置にします。 - 2つ目の要素は、
float: right;
を設定して右側にフロートさせます。 - 3つ目の要素にはリンクを設定します。
clear
のようなフロート解除の設定はしません。
- 1つ目の要素は、
- 2つ目のブロック要素には
content-visibility: hidden;
を設定します。- ブロック内の要素にはリンクを設定します。
- クリックするたびに、1つ目のブロック内のfixed要素が移動するボタンを用意します。
See the Pen content-visibilityの検証(content-visibilityプロパティを設定した場合) by ミツエーリンクス (@mitsue-links) on CodePen.
- 初期表示
- 1つ目の
auto
が指定されたブロックcontain
プロパティにpaint
を指定した場合と同じ見た目になります。- ブロック内のリンク要素はアクセシビリティツリーに表示されます(ブロックがオフスクリーンの場合も同様です)。
- ブロック内のリンク要素はフォーカス可能です(ブロックがオフスクリーンの場合も同様です)。
- ブロック内のリンク要素はスクリーンリーダーで読み上げられます(ブロックがオフスクリーンの場合も同様です)。
- 2つ目の
hidden
が指定されたブロック- margin、border、paddingのサイズ指定がある場合は、その指定したmargin、border、paddingのサイズは0にはならずにそのまま残ります。
- ブロック内のリンク要素はアクセシビリティツリーに表示されません。
- ブロック内のリンク要素にフォーカスできません。
- ブロック内のリンク要素はスクリーンリーダーで読み上げられません。
- 1つ目の
- ボタンをクリックして、fixed要素を移動
contain
プロパティにpaint
を指定した場合と同じ見た目になります。
W3Cの仕様にあるようにcontent-visibility: auto;
ではレンダリングのStyle、Layout、Paintの封じ込めが有効になります。
この検証からStyle、Layout、Paintの中のPaintの封じ込めが有効になることがわかります。
またcontent-visibility: hidden
を設定してレンダリングをスキップすると、タブ遷移によるフォーカスやスクリーンリーダーの読み上げなどのアクセシビリティに影響することがわかります。
パフォーマンスを比較
これまでの内容を踏まえ、content-visibility
プロパティの設定がないページとcontent-visibility
プロパティを設定したコンテンツを含むページを用意してパフォーマンスを比較しました。
content-visibility
プロパティの設定はファーストビューの表示に影響が出ないように、オフスクリーンにあるコンテンツのみとしました。
計測にはGoogle Chrome デベロッパーツールのLighthouseとPerformance Observerを使用しました。
Lighthouseで計測したFirst Contentful Paintの結果
計測回数 | content-visibility プロパティがない場合の計測値 |
content-visibility: auto; を設定した場合の計測値 |
---|---|---|
1 | 1880ミリ秒 | 1599ミリ秒 |
2 | 1867ミリ秒 | 1553ミリ秒 |
3 | 1952ミリ秒 | 1526ミリ秒 |
4 | 1926ミリ秒 | 1551ミリ秒 |
5 | 1856ミリ秒 | 1559ミリ秒 |
6 | 1891ミリ秒 | 1516ミリ秒 |
7 | 1893ミリ秒 | 1499ミリ秒 |
8 | 1844ミリ秒 | 1488ミリ秒 |
9 | 1965ミリ秒 | 1490ミリ秒 |
10 | 1883ミリ秒 | 1558ミリ秒 |
content-visibility プロパティがない場合 |
content-visibility: auto; を設定した場合 |
|
---|---|---|
中央値 | 1904.5ミリ秒 | 1543.5ミリ秒 |
平均値 | 1895.7ミリ秒 | 1533.9ミリ秒 |
Performance Observerで計測したfirst-contentful-paintの結果
計測回数 | content-visibility プロパティがない場合の計測値 |
content-visibility: auto; を設定した場合の計測値 |
---|---|---|
1 | 146ミリ秒 | 125ミリ秒 |
2 | 146ミリ秒 | 187ミリ秒 |
3 | 216ミリ秒 | 133ミリ秒 |
4 | 135ミリ秒 | 144ミリ秒 |
5 | 139ミリ秒 | 150ミリ秒 |
6 | 155ミリ秒 | 125ミリ秒 |
7 | 139ミリ秒 | 120ミリ秒 |
8 | 147ミリ秒 | 133ミリ秒 |
9 | 192ミリ秒 | 148ミリ秒 |
10 | 173ミリ秒 | 118ミリ秒 |
content-visibility プロパティがない場合 |
content-visibility: auto; を設定した場合 |
|
---|---|---|
中央値 | 146ミリ秒 | 133ミリ秒 |
平均値 | 155.9ミリ秒 | 136.3ミリ秒 |
Performance Observerで計測したloadEventEndの結果
計測回数 | content-visibility プロパティがない場合の計測値 |
content-visibility: auto; を設定した場合の計測値 |
---|---|---|
1 | 335ミリ秒 | 205ミリ秒 |
2 | 335ミリ秒 | 168ミリ秒 |
3 | 296ミリ秒 | 166ミリ秒 |
4 | 278ミリ秒 | 192ミリ秒 |
5 | 262ミリ秒 | 216ミリ秒 |
6 | 262ミリ秒 | 158ミリ秒 |
7 | 285ミリ秒 | 168ミリ秒 |
8 | 268ミリ秒 | 194ミリ秒 |
9 | 292ミリ秒 | 184ミリ秒 |
10 | 265ミリ秒 | 213ミリ秒 |
content-visibility プロパティがない場合 |
content-visibility: auto; を設定した場合 |
|
---|---|---|
中央値 | 278ミリ秒 | 185ミリ秒 |
平均値 | 289.8ミリ秒 | 188.4ミリ秒 |
計測した3つのパターン全てにおいて封じ込めを行ったほうが、若干表示パフォーマンスの改善が見受けられました。
さいごに
CSS ContainmentについてのBlogを3回に分けてご紹介してきました。 個人的にパフォーマンスを比較ではもう少し数値に差が出ることを期待していました。今後、パフォーマンス改善が必要なコンテンツで取り入れながら、引き続き効果的な使用方法を検証し、ご紹介していければと思います。