表示速度を飛躍的に向上させるHTML/CSS仕様「content-visibility」「Lazy loading」「contain」をコード付き簡単解説
LY Corp Tech Blogは、ウェブページの表示速度を大幅に向上させるHTML/CSS仕様「content-visibility」「Lazy loading」「contain」について、コード例を交えて実践的な解説を行っている。
キーポイント
content-visibilityによるレンダリング最適化
要素のレンダリングをスキップすることで初期表示を高速化し、スクロール時に必要な部分のみをレンダリングする仕組みを解説している。
Lazy loadingによる画像読み込み制御
ビューポート内に入った画像のみを読み込むことで、不要なネットワークリクエストを削減し、ページ読み込みを効率化する方法を説明している。
containプロパティによるレイアウト分離
要素のレイアウト計算範囲を限定することで、ブラウザの再レイアウト処理を最小限に抑え、パフォーマンスを向上させる手法を紹介している。
実装コード例と注意点
各仕様の具体的な実装コード例を示し、実際の適用時の注意点やブラウザ対応状況についても言及している。
影響分析・編集コメントを表示
影響分析
この記事はフロントエンド開発者にとって実用的なパフォーマンス最適化手法を提供しており、ウェブサイトのユーザー体験向上に直接貢献する内容である。ただし、AI業界との直接的な関連性は低く、汎用的なウェブ開発技術の解説に留まっている。
編集コメント
フロントエンド開発者向けの実践的な技術解説記事で、コード例が豊富で参考になるが、AI/機械学習との直接的な関連性は薄い。ウェブパフォーマンスに興味のある開発者には有用な内容。
この記事は、合併前の旧ブログに掲載していた記事(初出:2020年9月8日)を、現在のブログへ移管したものです。現時点の情報に合わせ、表記やリンクの調整を行っています。こんにちは、お久しぶりです。岡部和...
原文を表示
この記事は、合併前の旧ブログに掲載していた記事(初出:2020年9月8日)を、現在のブログへ移管したものです。現時点の情報に合わせ、表記やリンクの調整を行っています。
こんにちは、お久しぶりです。岡部和昌(@kzms2)と申します。
突然ですが、弊社ヤフーがW3Cという標準化団体に参加しているのはご存じでしょうか。
W3C(ダブリュースリーシー)とは、各種ウェブ関連技術の標準化を推進する非営利の標準化団体の名称です。正式名はWorld Wide Web Consortiumで、ティム・バーナーズ=リーによって1994年に設立されました。また現在は400を超える会員組織を擁しており、主要な規格はHTML、XML、MathML、DOMなどがあります。
ヤフーは2018年10月から、ウェブの各種技術の標準化を推進するW3Cに参加しています。
自分はその活動に関して積極的に取り組んでおり、今回はその活動下で得た表示速度改善系の情報で有益だと感じたものをいくつかコード付きで簡単に解説します。
随分と前から存在している仕様の説明もありますが、表示速度向上に関しての最新のナレッジも含めた内容をシェアできればと考えています。
まずはじめに
今回紹介する仕様などは以下の通りです。全て知っていたらそっとこの記事を閉じてください。
loading属性(Lazy loading)content-visibilityプロパティcontainプロパティ
content-visibilityプロパティが今回のイチオシなのですが、説明する順番的にまずはLazy loadingに触れたほうが理解しやすいので、その順番で説明していきます。また今回は要素の読み込みや表示を調整するモノに的を絞って説明していきます。
Lazy loadingとは画像がビューポート外にある時は読み込みを実行せず、ビューポートに近づいた時に画像の読み込みを開始する、表示速度を最適化する名称のことです。
値説明auto既定値。画像の読み込み方をブラウザの実装に委ねるlazyLazy loadingを有効にするeager画像をビューポート外でもすぐに読み込む(全ブラウザの基本動作)
これまではJavaScriptを用いて実装するしかありませんでしたが、ついにimgやiframe要素であればloading="lazy"を付与するだけで、簡単に実装できます。

画面外では読み込みが発生しないので、必要になった時(画面内に要素が入りそうになった時)に読み込みが発生するのでパフォーマンスが向上します。
また画像についてはsrcsetを用いたレスポンシブな画像に対しても指定できますし、picture要素を用いてfallback形式でも記述できます。


※読み込みの初期段階で表示させたい要素、例えばファーストビューのメイン画像などには付与しないのが望ましいです。
"loading属性"の対応ブラウザ
※対応ブラウザの表はIEはバージョン11で、その他は最新バージョンの対応状況です(2020年9月8日現在)
その他
ちなみにFacebookのソーシャルプラグインもLazy loading対応しているのですが、こちらはdata-lazy="true"と書き方が異なるので注意が必要です。(公式のページプラグイン - ソーシャルプラグイン(外部リンク)を参照ください)
※この書き方はW3Cの定義とは関係がないので、仕様というよりはFacebookのソーシャルプラグインだけに対する書き方だと思ってください
- content-visibilityプロパティ
2020年8月末リリースのChrome85に実装された機能で、本日記載している内容で一番新しい仕様です。
このプロパティが優れもので、指定した要素の描画をスキップして、ビューポートに近づくと描画 を行います。Lazy loadingはデータの読み込みを遅延実行し、一方で、content-visibilityは表示(レンダリング)を遅延実行します。
値説明visible既定値。要素の内容は、状態にかかわらずレイアウト・描画されるhidden要素の内容のレイアウト・描画をスキップする(display:none;と近い挙動)auto要素のレイアウト・スタイル・塗りの封じ込めをオンにする。要素はクライアントが表示を求めない状態の時にはスキップする(ビューポート外など)
content-visibility: auto;とその要素を描画する予定の高さの指定をcontain-intrinsic-sizeのプロパティを用いることによって使用できます。
…セクションの中身いろいろ
…別の内容のセクションの中身いろいろ
…そのまた別の内容のセクションの中身いろいろ
上記の指定だと、各sectionがビューポート外にある時は、高さを500pxを保持して中身がない状態で、描画がスキップされます。それにより無駄な描画をしないで済むので、読み込み速度が劇的に速くなります。
ただしcontain-intrinsic-sizeの値を適切に設定しないと、指定したsectionがビューポート内に近づいた時に要素の高さが変動してしまいます。概算でも良いのである程度「その要素が本来保持するであろう高さ」を設定してください。
"content-visibilityプロパティ"の対応ブラウザ
- containプロパティ
「レイアウト・スタイル・塗りの封じ込め」という表現が上記content-visibilityのauto値の説明で出てきましたが、このcontainプロパティの振る舞いが参考になるかもしれません。
content-visibility: auto;を要素に指定した場合、ビューポート外にある時はcontain: style layout size;が適用された状態に近いと考えてよいです。
ちなみにこのcontainプロパティ、Chrome52という随分前の段階ですでに実装されているので厳密に言うと最新の仕様ではありませんが、content-visibilityの影響もあってか最近仕様のアップデートが行われています。
値説明none既定値。封じ込めは行わないstrictcontain: size layout paint;と同等contentcontain: layout paint;と同等size指定した要素のサイズを封じ込め、子孫の影響をけないことを保証する。指定した時にはwidth, heightの指定をしないと要素の縦横幅がない状態で扱われることに注意layout指定した要素のレイアウトを封じ込め、親兄弟要素の影響を受けないことを保証するpaint指定した要素の外側に、子孫要素が描画されないことを保証するstyle指定した要素とその子孫以外に、影響を与える可能性のあるプロパティについて封じ込めることを保証する。この値は仕様書で「リスクあり」と明示されているので注意が必要
- style以外を封じ込めても問題ない要素
- style以外を封じ込めても問題ない要素
- style以外を封じ込めても問題ない要素
指定する値や条件にもよりますが大まかには以下のような状態です。
基本的にCSSの描画は一部が変更されただけでも全体の再レンダリングが必要となるのですが、このcontainプロパティを用いることで指定した箇所のCSSのツリーの指定した描画などを封じ込めて、その中でのレンダリングは全体に影響を及ぼさないようになります。
これだけ聞くと良い点しかないように感じられますが、レンダリングを封じ込めるということはその指定した要素の変更が全体のレンダリングに影響しなくなるということなので、例えば非同期で子要素が更新された時、閉じ込めた中身が想定よりもコンテンツが多かった場合は表示されず、表示崩れを起こしてしまいます。
おそらくは上記の「値の説明」を読んでも正直意味がわからない方が多数だと思うのですが、「その要素自身に対して指定した値は、親や兄弟とは別軸でレンダリングされる」と考えると良いかもしれません。
これらの挙動や振る舞いに関しての詳細は、ブラウザの描画に関しての知識が必要なので、「ブラウザ レンダリング」でヤフって見てください。
またの機会にここも掘り下げて書いてみたいと思っています。
"containプロパティ"の対応ブラウザ
まとめ
Lazy loadingをimgやiframeに実装したい!
loading="lazy"を該当要素に追加
画面外で要素の描画をスキップして表示を速くしたい!
content-visibility: auto;とcontain-intrinsic-size: 500px;を該当要素に指定(500のところは適宜書き換え)
描画領域が決まっている箇所、また非同期通信などで取得する要素の描画を速くしたい!
サイズが変化しない場合はcontain: strict;を、サイズが可変の場合にはcontain: content;を該当要素に指定(必要に応じて値は変更)
このどれもすべての要素に指定するなどの暴挙は行わず、必要と感じた箇所にのみ指定をしてください。優先的に読み込みたい・表示させたい要素には指定しないことをオススメします。
また新しく追加された仕様ということもあって、仕様自体に変更が入る可能性が十分にありえます。W3CやWHATWGなどの一次ソースの確認を定期的に行い、仕様に変化が出ていないかなどの確認を行ってください。
情報を追う自信がない方は、岡部のTwitter(@kzms2)をフォローしておいていただければこれらの情報は必ずつぶやきます。
最後に一言と注意点
いかがでしたか。対応ブラウザに偏りがあるものの、比較的簡単に実装できることがわかったかと思います。注意点を強いて挙げるならば、まだ実装されたばかりなので、バグがある可能性、仕様が変更される可能性がある という点でしょうか。実際にcontain: style;に関しては最近でも仕様の扱い方が揺れ動いています。
UIやデザインには好みがあるけど、ページが速く表示されて文句言う人はいない です。
今回はこれらの内容について 「簡易的に理解をしたい」 という方向けに書きました。仕様や詳細に関しては最後に参考リンクを貼っておくので、原文を見に行って読むことをとてもオススメします。
参考リンク(外部リンク)
loading属性
HTML StandardAddyOsmani.com - Native image lazy-loading for the web!picture要素
HTML Standard
content-visibilityプロパティ
CSS Containment Module Level 2content-visibility: the new CSS property that boosts your rendering performance
containプロパティ
CSS Containment Module Level 2
関連記事
差分表示のパフォーマンス向上への挑戦
GitHubが、大規模なプルリクエストでも高速に動作するReactベースの新しい「変更されたファイル」タブを全ユーザー向けにリリースした。
プレゼンテーション:スケールにおける速度:最大級のCXプラットフォームを最適化する
Matheus Albuquerqueが、React 15とWebpack 1から最新標準への移行を含む大規模CXプラットフォームの最適化戦略を共有し、ASTベースのコードモッドによる大規模移行、モジュール/ノンモジュールを用いた差分配信、Preactによるフットプリント縮小について説明している。
Pretext
Reactコア開発者のCheng Lou氏が、DOMに触れずに折り返しテキストの高さを計算する新しいブラウザライブラリ「Pretext」を発表した。