【入門編】 content-visibilityによるレンダリング最適化 – Webブラウザの仕組み実践ガイド

こんにちは!Webの裏側を覗くのが大好きな、フロントエンド・アーキテクトの私です。

日頃からモダンでリッチなWebサイトを作っていると、どうしても避けられない壁にぶつかりますよね。「ページが縦に長すぎて、スマホでのスクロールがカクカクする」「画像やアニメーションを詰め込みすぎて、最初の読み込みが重い……」といった悩みです。

「画面に映っていない下の方のコンテンツなんて、最初から描画しなきゃいいのに!」

そう思ったことはありませんか? 実は、その長年の願いを魔法のように叶えてくれる素晴らしいCSSプロパティがあるんです。それが今回お話しする `content-visibility` です。

今回は、この `content-visibility` がブラウザの裏側でどんな魔法を使っているのか、身近な例えを交えながら一緒に優しく紐解いていきましょう。難しい用語にビビる必要は全くありませんよ。一つずつゆっくり見ていきましょうね。

—

1. ブラウザが画面を作る仕組み:レストランの「仕込み」と「営業」の例え

まず、Webブラウザが私達の目の前にページを表示する仕組みを、ちょっとレストランに例えてお話ししますね。

あなたが大きなレストラン(Webページ)を経営していると想像してください。お客さん(ユーザー)がお店に入ってきます。
もし、お客さんがまだ見えていない「一番奥の個室」や「2階の宴会場」の料理まで、来るかどうかも分からないのに最初から全部作って並べておいたらどうなるでしょうか?

  • キッチンのコンロはフル稼働(CPUやメモリの爆食い)
  • スタッフはヘトヘト(ブラウザのメインスレッドがフリーズ)
  • 結果、お客さんへの料理の提供が遅くなる(ページ全体のカクつき)

大変ですよね。賢いレストランなら、お客さんが実際にその席に座り、メニューを開いたタイミングで初めて調理(レンダリング)を始めますよね。

実は、これまでのブラウザは真面目すぎて、画面の遠く下の方にあるコンテンツまで、最初からせっせと「料理の仕込み(DOMの解析やスタイル計算、レイアウト計算)」を全部やっちゃっていたんです。そりゃあ重くなるわけです。

2. 救世主 `content-visibility: auto` の登場

そこで登場するのが、今回の主役 `content-visibility` です。

これをCSSの特定のまとまり(ブロック要素など)に指定してあげると、ブラウザに対してこんな指示を出せるようになります。

> 「ねえブラウザさん、今このエリアは画面の外(お客さんの視界の外)にあるから、中身の細かい計算や描画はしなくていいよ! 画面に入ってきたら本気を出してね」

これを一番手っ取り早く、かつ劇的な効果を発揮させる魔法のキーワードが `auto` です。

実際にコードを見てみましょう。身構えなくて大丈夫ですよ。たった1行、CSSに書き足すだけです。

/ 縦に長いブログの記事一覧や、商品カードのコンテナなどに指定します /
.article-card {
/ 画面外にある時は、ブラウザに「中の計算をサボっていいよ」と伝えます /
content-visibility: auto;

/ さらに、ブラウザに「大体の高さを教えてあげる」ことで、
スクロールバーがガクッと動くのを防ぎます(後で詳しく解説します!) /
contain-intrinsic-size: 0 300px;
}

たったこれだけです。これだけで、ブラウザは画面の外にある `.article-card` の中身の複雑な計算をパタッと止めてくれます。

どれくらい劇的に軽くなるの?

体感として、「うわ、スクロールが羽が生えたように軽くなった!」と感動するレベルで変わります。
特に、数千行ある長いリストや、画像とテキストが延々と続くポートフォリオサイトなどでは、初期表示の速度(LCPやTBTといったWebの健康診断の数値)が文字通り「桁違い」に改善されることがあります。ブラウザの省エネモードをONにしたような感覚ですね。

—

3. ちょっと待って!導入時に気をつける「つまずきポイント」

「おっ、じゃあサイト全体の親要素に全部 `content-visibility: auto` を貼っちゃえば無敵じゃん!」と思ったそこのあなた。ちょっと待ってくださいね。

魔法には、少しだけお作法(ルール)があります。ここがつまずきやすいポイントなのですが、私が優しくフォローしますので安心してください。

① スクロールバーが「あれっ?」と暴れる現象

画面外のコンテンツの計算をスキップするということは、ブラウザからすると「中に何が入っていて、縦の長さがどれくらいあるのか分からない状態」になります。

そのため、ページをスクロールしている最中に「あ、この要素が見えてきた!……おっと、中身はこんなに高さがあったのか!」とブラウザが後から気づき、スクロールバーがガクンと伸び縮みする(レイアウトのシフトが起きる)という現象が起きます。これはユーザーにとってちょっと気持ち悪いですよね。

② 対策:`contain-intrinsic-size` で「大体の大きさ」を教えてあげる

そこで先ほどのコードにも出てきた `contain-intrinsic-size`(インダストリアル・サイズ……ではなくて、固有サイズの設定です)の出番です。

これは、ブラウザに対して「中身の正確な高さは分からないかもしれないけど、大体高さは 300px くらいだから、そのつもりでスペースを空けといてね!」とあらかじめ伝えておくための「仮のサイズ予約席」券です。

.article-card {
content-visibility: auto;
/ 横幅は自動、高さの仮置きを 300px に指定する /
contain-intrinsic-size: auto 300px;
}

これをしておけば、スクロールバーが暴れるのをピタッと防ぎつつ、レンダリングの最適化の恩恵だけをしっかり受けることができます。なんて親切な設計なんでしょう!

—

4. 実践!サンプルコードで動きを確認してみよう

それでは、実際にエディタに貼り付けて試せるシンプルなHTMLとCSSのセットを見てみましょう。
ご自身のローカル環境に保存して、ブラウザのデベロッパーツール(検証ツールの「Rendering」タブにある「Paint flashing」など)で、画面外の要素が描画の対象外になっている様子をぜひ観察してみてください。





content-visibilityの体感デモ


スクロールしてパフォーマンスの違いを感じよう

画面の外にあるカードの中身は、ブラウザの描画お休みモードになっています。

カードその2

このあたりはまだ画面の外です。ブラウザは省エネモードで待機中。

カードその3

スクロールしてこの要素が画面に入ってきた瞬間、ブラウザがシャキッと目を覚まして描画を行います。

カードその4

DOMの要素数が膨大になる長いページでも、これならスマホのCPUが悲鳴を上げずに済みますね。

カードその5

最後のカードです。お疲れ様でした!


—

5. さいごに:チーフアーキテクトからのエール

Webの技術は日々進化していますが、根本にあるのは「いかにユーザーにストレスのない、心地よい体験を届けるか」という温かい心遣いです。

`content-visibility` は、一見すると少し難しそうなブラウザの内部の仕組み(レンダリング)に直接アプローチできる、フロントエンドエンジニアにとって非常に強力な武器です。「なんだか最近、サイトの動きがもっさりするな……」と悩んだときは、ぜひ思い出して、いつものCSSにそっと書き加えてみてください。

きっと、あなたの作ったWebサイトが、見違えるように軽やかに、そして軽快に動き出してくれますよ。
もし分からないところでつまずいたら、いつでも立ち止まって、ブラウザが一生懸命お仕事をしている姿を想像してあげてくださいね。それでは、楽しいコーディングライフを!

コメント

タイトルとURLをコピーしました