レンダリングの「サボり方」を知る者こそが、Webを速くする。`content-visibility`の深淵
フロントエンドの現場で「サイトが重い」という課題にぶつかったとき、君たちはまず何をする? 画像の圧縮? バンドルサイズの削減? もちろんそれらは基本だ。だが、ブラウザの「レンダリングエンジン」という巨大な工場が、今まさに何をしているか想像したことはあるか?
実は、ブラウザは画面外にある要素であっても、律儀にDOMを解析し、スタイルを計算し、レイアウトを確定させようとする。正直な話、「見えていないものの計算にCPUを費やす」のは、リソースの無駄遣いなんだ。
今日紹介する `content-visibility` は、そんなブラウザの「過剰な親切心」を制御し、必要なときだけレンダリングさせるための魔法の杖だ。
—
1. ブラウザの苦悩:なぜ初期ロードは遅くなるのか
ブラウザはHTMLをパースしてDOMツリーを作り、CSSを当ててCSSOMを作り、それらを組み合わせて「レンダーツリー」を構築する。この「レイアウト計算(Reflow)」と「描画(Paint)」は、ブラウザにとって最も重い作業の一つだ。
特に、数千行ある長い記事ページや、無限スクロールのようなDOMノードが膨大になるページでは、ブラウザはユーザーが一度も見ないかもしれないフッター付近の計算まで、律儀に実行しようとする。これが初期ロードのボトルネックだ。
`content-visibility: auto` を指定すると、ブラウザはこう判断する。
「お、この要素は今画面外にあるから、レイアウトや描画の計算をスキップしていいんだな?」
これだけで、ブラウザの負荷は劇的に軽くなる。これが「レンダリングの遅延評価」だ。
—
2. 現場で直面する「崩れ」の正体と解決策
ただし、魔法には代償がある。ブラウザが「まだ見えていない要素」の計算をサボると、ブラウザは「その要素がどれくらいの高さなのか」を判断できなくなる。
するとどうなるか? スクロールバーがガタついたり、要素が出現した瞬間にページ全体がガクンとジャンプする現象が起きる。これを防ぐために必須なのが `contain-intrinsic-size` だ。
これは「レンダリングをサボっている間の、仮のサイズ」を指定するプロパティだ。ブラウザに「中身は後で計算するから、とりあえずこの高さ分だけスペースを空けておいてくれ」と指示を出すわけだ。
—
3. 実践:明日から現場で使えるコード例
百聞は一見に如かず。実際に、大量のカードが並ぶコンポーネントでこの最適化を適用してみよう。
.card-container {
/
- auto: 画面外にあるときはレンダリングをスキップする
- これにより、ブラウザはスタイル計算やレイアウト計算を大幅に削減する
/
content-visibility: auto;
/
- レンダリングをスキップしている間の高さ(プレースホルダーサイズ)
- 実際のコンテンツの平均的な高さを指定するのがコツ
- ここを適当にすると、スクロールバーが激しく暴れるので注意!
/
contain-intrinsic-size: 0 500px; / 横幅は自動、高さは500pxと仮定 /
}
.hidden-content {
/
- hiddenを指定すると完全にレンダリングを停止する
- 特定のモーダルや、動的に出し入れする重いコンポーネントに有効
/
content-visibility: hidden;
}
実務での運用の勘所
1. `contain-intrinsic-size` の値は「概算」でいい: 完璧な数値を出す必要はない。ただし、あまりに実態と乖離しているとスクロールバーが不自然な動きをする。DevToolsの「Layout Shift」を監視しながら、現実的な数値を当てはめてくれ。
2. どこにでも貼ればいいわけではない: `content-visibility: auto` は、ある程度独立した大きなブロック(セクションやカード単位)に適用するのが最も効果的だ。インライン要素や小さな文字一つ一つに適用するのは、逆にブラウザのオーバーヘッドを増やす可能性がある。
3. アクセシビリティへの配慮: `content-visibility: hidden` を使う場合、ブラウザからは「見えない(存在しない)」とみなされる。フォーカスが当たったり、スクリーンリーダーが必要な要素には使わないようにしよう。
—
最後に:ブラウザと「対話」せよ
エンジニアとして一段上のレベルに行くためには、ブラウザを「ただの表示器」として扱うのをやめるべきだ。ブラウザは、最適化の余地を常に残している。
`content-visibility` は、君たちがブラウザのエンジンの内部構造を理解し、彼らの負荷を適切に管理するための強力な武器になるはずだ。
まずは、重い管理画面や長いLPのリストの一部に、このプロパティを仕込んでみてほしい。Lighthouseのスコア(特にTBT: Total Blocking Time)が目に見えて改善する瞬間、君はブラウザという機械と少しだけ「会話」ができるようになったと感じるはずだ。
現場で躓くことがあれば、またいつでも聞いてくれ。技術的な深掘りは、いくらでも付き合うぞ。

コメント