今年2020年8月、アップデートによりCSSプロパティ「content-visibility」がChrome85にて実装されました。
「content-visibility」では、値を「auto」に設定することによって指定した要素がビューポート(表示中の画面内)に表示されるまで、レンダリング(読み込んだデータを整形して表示すること)を実行しないというような動きが可能になります。
その結果不要なレンダリングが実行されなくなり、サイト全体の表示速度を改善することができます。
今回は「content-visibility」の詳細な仕組みや実装方法などをご紹介し、実際に速度検証をしていこうと思います。
レンダリングの遅延実行について
以前ラボ内のこちらの記事で似たような機能としてlazy-loadの画像遅延読み込みについて解説されているので、一度目を通していただきたいのですが、簡単に言うとこちらの「読み込み」を「表示」に置き換えて解釈していただければ問題ありません。
ビューポート外でもページ内要素のレンダリングを実行するのが全ブラウザの基本動作となっていますが、遅延実行はビューポート内に達するまでレンダリングを行わないことを指します。
content-visibilityの実装方法
content-visibilityプロパティでは、以下の値を指定することができます。
値 | 説明 |
visible | 要素がビューポート外でも表示される。既定値。 |
auto | 要素がビューポート内の場合のみ表示される。 |
hidden | 要素がビューポート内でも表示されない。 (「display: none;」と似たような挙動) |
実装方法は、他のCSSプロパティと同様に
[指定したい要素] { content-visibility: auto; }
とすることで、簡単に実装できます。
注意点として、レンダリングを遅延実行させる値は「auto」ですが、「auto」に設定する際には同じ要素に対して以下のプロパティを追加する必要があります。
contain-intrinsic-size: (任意の値)px;
理由としては、ビューポート外でレンダリングされていない要素は中身が空の要素として振る舞い、ビューポート内に達するまでは高さが0pxとして扱われます。
これによりスクロールバーが正しく表示されなくなってしまうため、「contain-intrinsic-size」プロパティで本来の要素の高さを指定する必要があります。
高さ指定については、おおよその値で問題ありません。
つまり、実際に値を「auto」に設定する際はこのような記述となります。
[指定したい要素] { content-visibility: auto; contain-intrinsic-size: (任意の値)px; }
content-visibilityによるメリット
<content-visibility: auto; >の場合
サイト表示速度の改善
本記事におけるメインとなります。
レンダリングが遅延実行されるようになり、ビューポート外の不要なレンダリングが減ることで、結果的にサイト全体の表示速度を改善することができます。
表示速度が速くなることで、サイト直帰率・離脱率を低下させ、CVRの向上に繋がります。
またSEOの観点からも、ページの表示速度が遅いことによるランキング要素への影響を、モバイル検索・PC検索ともになくすことができます。
<content-visibility: hidden; >の場合
描画コストの軽減
こちらは本記事の主旨とは少し外れますが、せっかくの機会なのでご紹介させていただければと思います。
何らかの作業・条件によって初めて要素を表示させたい場合、CSSを用いてdisplay: none;で要素を非表示にしておいてから再度表示する、といった方法を取ることがあると思います。
このとき、display: none;の代わりにcontent-visibility: hidden;で要素を非表示にすることによって、表示する際の描画コストを抑えることができます。
レンダリングについて、「読み込んだデータを整形して表示すること」と上述しましたが、厳密には「レンダリングで整形した後、描画する」という工程を踏んでいます。
display: none;で要素を非表示にした場合、表示する際に一からレンダリングで整形・描画をする必要があります。
しかしcontent-visibility: hidden;で要素を非表示にした場合、非表示ではありますがレンダリングでデータを整形済みのため、表示する際に少ないコストで描画することが可能です。
速度検証
以下の比較ページにをcontent-visibility: auto; を記述した場合とそうでない場合で、実際にページを読み込む速度を比較しました。
ページのデータ量は180MBとなっております。
・http://sawamoto-test.aispr.jp/not_visibility
→content-visibility非適用ページ
・http://sawamoto-test.aispr.jp/visibility
→content-visibility適用ページ
記述したCSSは以下の通りです。
img { content-visibility: auto; contain-intrinsic-size: 650px; }
デベロッパーツール
・検証方法
キャッシュを削除した上でリロードし、Chromeのデベロッパーツール > Networkで計測。
下記の値を抽出し、10回計測した平均値とページごとの差を求める。
Finish | ページの表示が完了するまでの時間 |
Load | ページ内コンテンツの読み込みが完了するまでの時間 |
・結果
Finish | -0.644秒 |
Load | -1.194秒 |
PageSpeed Insights
・検証方法
PageSpeed Insightsの「モバイル」で下記の値を抽出し、10回計測した平均値とページごとの差を求める。
スコア | ページ表示速度に対する点数(0~100) |
First Contentful Paint | コンテンツまたは、画像が初めて表示されるまでの時間 |
Time to Interactive | ユーザーがページの操作が可能になるまでの時間 |
Speed Index | ページ内コンテンツが見えるまでの時間 |
Total Blocking Time | First Contentful PaintからTime To Interactiveまでの間で発生する50msを超えるメインスレッドのタスクのうち、Blocking Time(ユーザーの入力応答を阻害する時間)の合計時間 |
Largest Contentful Paint | ページで最も大きな要素が読み込まれるまでの時間 |
・結果
スコア | +12.3点 |
First Contentful Paint | +0.01秒 |
Time to Interactive | -0.34秒 |
Speed Index | +9.79秒 |
Total Blocking Time | -0.452秒 |
Largest Contentful Paint | -33.7秒 |
以上の検証結果より、content-visibilityを記述するだけでページ表示速度が改善されていることがわかります。
今回検証したページでは体感的にわかりづらいかもしれませんが、コンテンツが多いページほどより効果を見込めるはずです。
まとめ
比較的簡単に実装でき、サイト表示速度の改善が見込めることはおわかりいただけたでしょうか。
最後に、content-visibilityを導入する際には
・実装されて比較的間もないため、バグがある可能性や仕様が変更される可能性がある
ということと、さらには
・対応ブラウザがChromeのみ
といった点にご注意ください。
とはいえ、Chromeのブラウザシェア率は年々増加していますし、実装したところでChrome以外のブラウザで悪影響が出るようなプロパティでもないため、ぜひ積極的に活用してみてはいかがでしょうか。