【実務・中級編】 レンダリング指標(LCP, CLS)の技術的背景 – Webブラウザの仕組み実践ガイド

ブラウザの「脳内」を覗く:LCPとCLSが教えてくれるレンダリングの真実

「LCPが悪い」「CLSが改善しない」。そんな指摘をLighthouseから突きつけられ、なんとなく `width` を指定したり、画像を圧縮したりして終わらせていないだろうか?

現場で長く戦っていると痛感するが、Webブラウザは単なる「HTML表示機」ではない。あれは、非同期で送られてくる断片的なデータから、「今、ユーザーに何を見せるのが一番誠実か」を必死に計算し続ける、極めて高度な推論エンジンだ。

今日は、その推論プロセスの隙間に潜むLCP(Largest Contentful Paint)とCLS(Cumulative Layout Shift)の正体に迫ろう。

—

1. LCPの正体:ブラウザは「何が主役か」をどう判断しているのか?

LCPを単なる「読み込み時間」と捉えてはいけない。これは、ブラウザがレンダリングの過程で「どれがこのページの顔(Hero Element)か?」をマークし続けている履歴そのものだ。

ブラウザ内部の動き

ブラウザは、HTMLをパースしてDOMを組み上げ、CSSOMとマージしてRender Treeを作る。この時、ブラウザは「Largest(最大)」な要素を特定するために、以下の要素を常に監視している。

  • `` 要素
  • `` 内の `` 要素
  • `
  • `url()` で指定された背景画像を持つ要素
  • テキストノードを含むブロックレベル要素

ここが重要だ。 ブラウザは、これらの要素が画面内に登場するたびにサイズを計算し、最大のものを選び出す。そして、その要素が「描画(Paint)」された瞬間のタイムスタンプを記録する。つまり、LCPを改善する鍵は「ブラウザにどれが主役か早く教え、それを邪魔するものを排除すること」に尽きる。

2. CLSの正体:レイアウトの「再計算」という罪

CLSは、ブラウザが「一度描画したものを、後から強引に書き換える」時に発生する。これはブラウザにとって、非常にコストの高い「後悔のプロセス」だ。

ブラウザは一度描画した位置を計算し終えた後、例えば遅延読み込みの画像が降ってきて高さが確定した瞬間に、下のコンテンツを押し下げる。ブラウザは「え、聞いてないよ!」と叫びながら、レイアウトを再計算し、画面全体を再描画(Repaint)する。この「ガクッ」という動きが、ユーザー体験を損なうCLSの正体だ。

—

3. 実践:ブラウザを迷わせないための「先回り」コード

ブラウザを救うのは、私たちエンジニアが提供する「事前のヒント」だ。以下のコードは、現場で私が「最低限これだけは守れ」と伝えているプラクティスだ。

/

  • LCPとCLSを監視し、ボトルネックを特定するためのスクリプト
  • 本番環境で「どこで指標が落ちているか」を把握するために使います

/

// 1. LCPの監視
// ブラウザがどの要素を「最大」と判断したかを知ることで、最適化の対象が明確になります
new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
const lastEntry = entries[entries.length – 1];
console.log(‘LCPの対象要素:’, lastEntry.element?.tagName, lastEntry.element?.id);
console.log(‘LCP発生時間:’, lastEntry.startTime);
}).observe({ type: ‘largest-contentful-paint’, buffered: true });

// 2. CLSの監視
// どの要素がレイアウトシフトを引き起こしているか、具体的に特定します
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
if (!entry.hadRecentInput) { // ユーザー操作による移動は除外
console.warn(‘レイアウトシフトが発生:’, entry.value);
// どの要素が動いたかを確認する
entry.sources.forEach(source => {
console.log(‘原因となった要素:’, source.node);
});
}
}
}).observe({ type: ‘layout-shift’, buffered: true });

実務レベルのTips:

1. アスペクト比の固定: `aspect-ratio` をCSSで指定すれば、画像が読み込まれる前にブラウザは「ここにこれくらいの箱が必要なんだな」と予約できる。これが最強のCLS対策だ。
2. `fetchpriority=”high”`: LCP候補(メインビジュアルなど)には、ブラウザに「これは最優先だ」と伝える呪文を唱えよう。
3. フォントの読み込み: `font-display: swap` は便利だが、FOUT(フォント切り替えによるレイアウト崩れ)を引き起こす。可能な限り、システムフォントとのフォントメトリクスを調整しておくのがプロの仕事だ。

—

最後に:ブラウザは「パートナー」である

LCPやCLSといった指標は、単なるGoogleからの採点ではない。ブラウザが「ユーザーに快適な体験を届けるために、今こんなに苦労しているよ」と発している悲鳴だ。

その仕組みを理解し、ブラウザの先回りをすることで、Webサイトは驚くほど軽快に動くようになる。泥臭い計測と、ちょっとしたCSSの配慮。これだけで、あなたの作るWebサイトの品格は一段階上がるはずだ。

次は、実際に計測ツールをコンソールに貼り付けて、君のサイトの「主役」が誰なのかを確認することから始めてみてほしい。現場からは以上だ。

コメント

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