LCP

ビューポート内の最大コンテンツ要素が表示されるまでの時間を測定する Core Web Vitals の指標

パフォーマンスSEO

LCP とは

LCP (Largest Contentful Paint) は、ビューポート内で最も大きなコンテンツ要素 (画像、動画、テキストブロック) が表示されるまでの時間を測定する Core Web Vitals の指標である。ユーザーが「ページが表示された」と感じるタイミングを数値化する。

スコア評価
0〜2.5 秒良好 (Good)
2.5〜4.0 秒改善が必要
4.0 秒以上不良 (Poor)

このしきい値は 1 回の計測値に当てるものではなく、実ユーザーの読み込みの分布に当てる。良好と判定されるには、モバイルとデスクトップそれぞれで 75 パーセンタイルの LCP が 2.5 秒以内である必要がある。手元の光回線で 2.0 秒が出ていても、遅い回線や低速端末を含む実データの 75 パーセンタイルが 3.2 秒なら評価は「改善が必要」になる。計測の起点は、原則としてユーザーがそのページへ遷移した時刻である。

LCP の対象要素

  • <img> 要素、および <svg> 内の <image> 要素
  • <video> 要素 (ポスター画像と動画の最初のフレームのうち早い方)
  • CSS の url() で読み込まれた背景画像 (グラデーションは対象外)
  • テキストを含むブロックレベル要素 (<h1>, <p> など)

ほとんどのページでは、ヒーロー画像やメインビジュアルが LCP 要素になる。

候補には除外規則がある。2026 年 8 月時点の Chromium では、opacity: 0 で不可視の要素、ビューポート全面を覆う要素 (背景とみなされる)、プレースホルダーのような低エントロピー画像 (表示面積に対して情報量が極端に少ない画像) は候補から外れる。単色の板や極端に粗いぼかし画像を先に描いても LCP が改善しないのはこの規則によるもので、計測されるのは差し替えた本画像が描かれた時刻である。

LCP が遅くなる 4 つの原因と対策

1. サーバーレスポンスが遅い (TTFB)

対策:
- CloudFront で静的コンテンツをキャッシュ
- Lambda のコールドスタートを最小化
- サーバーサイドレンダリング (SSR) の最適化

2. LCP 画像の読み込みが遅い

<!-- ❌ 遅延読み込み: LCP 画像には使わない -->
<img src="hero.jpg" loading="lazy" alt="Hero">

<!-- ✅ 優先読み込み: LCP 画像は fetchpriority="high" -->
<img src="hero.jpg" fetchpriority="high" alt="Hero">

<!-- ✅ プリロード: head に置き、本文の要素の解析を待たずに取得を開始 -->
<link rel="preload" as="image" href="hero.jpg" fetchpriority="high">

fetchpriority="high" は取得の順番を上げる指定で、ブラウザーが要素を見つけるタイミング自体は変えない。<link rel="preload"> が効く理由はそことは別で、<head> を走る先読み解析が、本文の解析や CSS の適用を待たずに URL を取り出せる点にある。したがって preload の効果が大きいのは、CSS の background-image や JavaScript が後から挿入する画像のように、HTML を素読みしただけでは発見できない画像である。逆に <head> の近くにある <img> へ preload を重ねても取得開始はほとんど早まらず、同時取得が増えて他のリソースを押しのける副作用だけが残ることもある。

3. レンダリングをブロックするリソース

<!-- ❌ 同期的な CSS/JS がレンダリングをブロック -->
<link rel="stylesheet" href="large-library.css">
<script src="analytics.js"></script>

<!-- ✅ クリティカル CSS をインライン化、非クリティカルを遅延 -->
<style>/* クリティカル CSS */</style>
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">
<script src="analytics.js" defer></script>

4. クライアントサイドレンダリング

SPA で JavaScript が実行されるまでコンテンツが表示されない。SSR/SSG でサーバー側で HTML を生成し、初期表示を高速化する。

Next.js での LCP 最適化

next/image の loading の既定値は lazy である。つまりヒーロー画像をそのまま置くと、遅延読み込みによって自分で LCP を遅らせることになる。ファーストビューの画像だけは優先度を明示する。

import Image from 'next/image';

// next/image は形式変換とリサイズを自動化するが、loading の既定は lazy
// ファーストビューの画像は取得優先度を上げる
<Image src="/hero.jpg" alt="Hero" width={1200} height={630} fetchPriority="high" />

2026 年 8 月時点の Next.js 16 では priority が非推奨になり、<head> へ <link rel="preload"> を挿入する役割は preload という別の props に分かれた。公式ドキュメントは多くの場合 preload より loading="eager" か fetchPriority="high" を勧めている。とくに画面幅ごとに別の画像を出し分ける構成では preload を使うと両方の画像を取得してしまうため、fetchPriority="high" を選ぶ。Next.js 15 以前では priority が同じ役割を担う。

測定方法

ラボ計測 (Lighthouse) と実ユーザー計測は別物で、検索での評価に使われるのは後者である。PageSpeed Insights は同じ画面に両方を並べるため、実データ欄が「改善が必要」でラボ欄が「良好」という食い違いは日常的に起きる。優先すべきは実データ側で、ラボ計測は原因の切り分けに使う。

# Lighthouse
npx lighthouse https://example.com --only-categories=performance

# PageSpeed Insights (実ユーザーデータ + ラボデータ)
# https://pagespeed.web.dev/
// JavaScript で LCP をリアルタイム測定
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];
  console.log('LCP:', lastEntry.startTime, 'ms');
}).observe({ type: 'largest-contentful-paint', buffered: true });

この観測は、ブラウザーがユーザーの操作 (タップ、スクロール、キー入力) を検知した時点で新しい候補の報告を止める。手で触りながら計測すると LCP が実際より小さく出るため、自動計測では操作を挟まないようにする。

体系的に学ぶなら関連書籍を参照してほしい。

共有:

この記事は役に立ちましたか?

関連用語

関連する記事