Next.js next/image 実運用最適化 2025 — LCP/INPと画質の両立

公開: 2025年9月23日 · 読了目安: 5 · 著者: Unified Image Tools 編集部

はじめに

next/image は最適化とレイアウトの型を与えてくれる一方、使い方を誤ると LCP を改善しながら INP を悪化させることがあります。特に、ヒーロー画像に過度な優先度を与えたり、折り返し下の大量画像がユーザー入力直後に一斉デコードされると、応答が鈍ります。

本稿は、INP 中心の記事 INP中心の画像配信最適化 2025 — decode/priority/スクリプト協調で体感を守る のフレームに沿って、Next.js(App Router)での画像最適化を「レイアウト」「優先度」「タイミング協調」の観点から体系化します。

TL;DR

  • LCP候補は fetchpriority="high"preload の両輪で先行取得
  • sizes の明示と aspect-ratio でCLSゼロを実現
  • priority-hints を多用しすぎない。INPを悪化させないリソース配分
  • next/imageplaceholderはLQIPかCSSプレースホルダーで十分。重いSVGは避ける

内部リンク: INP中心の画像配信最適化 2025 — decode/priority/スクリプト協調で体感を守る, 画像の優先度設計とpreloadの最適解 2025, 2025年のレスポンシブ画像設計 — srcset/sizes 実践ガイド

なぜ next/image が INP に影響するのか

ブラウザは「ネットワーク取得 → デコード → レイアウト/描画」の段階を踏みます。next/image 自体は最適化に寄与しますが、以下の条件が重なると INP を悪化させます。

  • 入力直後(タップ/スクロール)に LazyLoad が大量発火 → デコードとイベント処理が競合
  • priority の乱用でネットワークが飽和 → 下位の重要スクリプトが遅延
  • 不正確な sizes で過配信 → デコード時間が増え、LCP と INP を同時に悪化

鍵は「適正サイズ」「優先度の最小化」「タイミングの分離(協調)」です。

運用ポイント(設計プリンシプル)

  • クリティカルパス: Hero/LCPはhigh、他はauto/遅延
  • fill/sizesの使い分け: レイアウト固定か可変かで選択
  • カラー: sRGB固定での一貫性、P3は対応環境の検証を前提

実装断片

<Image src="/hero.avif" alt="" priority fetchPriority="high" sizes="100vw" />

ポイント:

  • LCP 候補のみ priority(Next.js)/fetchPriority="high"(ブラウザ)を併用
  • sizes はレイアウト実寸に一致させる。可変レイアウトではブレークポイント別に文字列で指定
  • width/height(固定レイアウト)または fill + aspect-ratio(可変レイアウト)で CLS をゼロに

典型アンチパターンと対策

  • すべてのファーストビュー画像に priority を付与 → ヒーロー(またはカルーセル1枚目)のみに限定
  • 折り返し直下の 20 サムネが視界に入って一斉に lazy デコード → rootMargin: '300px 0px' で段階ロード
  • sizes が 100vw 固定で実寸より大 → 必要幅を見積り、(max-width: 768px) 92vw, 360px のように具体化
  • ヒーローに凝った SVG プレースホルダー → 軽量 LQIP/CSS プレースホルダーで十分

next/image のサイズ設計(実例)

固定幅カード:

<Image
  src="/cards/card.avif"
  alt=""
  width={360}
  height={240}
  sizes="(max-width: 768px) 92vw, 360px"
  loading="lazy"
  decoding="async"
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
  style={{ objectFit: 'cover' }}
/> 

フル幅ヒーロー(可変):

<div style={{ position: 'relative', aspectRatio: '3 / 2' }}>
  <Image
    src="/hero/cover.avif"
    alt=""
    fill
    sizes="100vw"
    priority
    fetchPriority="high"
    decoding="sync"
  />
  {/* テキストオーバーレイ等 */}
  <h1 className="sr-only">製品名</h1>
  
</div>

注意:

  • fill を使う場合、親に position: relativeaspect-ratio を必ず与える
  • decoding="sync" は LCP 候補のみ。他は async でメインスレッドの余地を残す

リソースヒントと preconnect/preload

preconnect は CDN を初回から叩く場合のみ。乱用は逆効果です。preload は 1 枚の LCP 候補 に絞ります。

export const metadata = {
  other: {
    link: [
      { rel: 'preconnect', href: 'https://cdn.example.com', crossOrigin: 'anonymous' },
      // { rel: 'preload', as: 'image', href: '/hero-1536.avif', imagesrcset: '/hero-768.avif 768w, /hero-1536.avif 1536w', imagesizes: '100vw' },
    ],
  },
};

内部リンク: 画像の優先度設計とpreloadの最適解 2025

プレースホルダー戦略(INPフレンドリー)

  • 目的は CLS と主観的快適さ。重い生成は不要
  • ヒーローに強いブラーは不要。プログレッシブな「見せかけ」は INP を改善しない
  • LQIP/BlurDataURL/CSSグラデを簡潔に使い、視覚の破綻(ちらつき)を防ぐ

関連: プレースホルダー設計 LQIP/SQIP/BlurHash の実践 2025

CDN最適化: 変換とキャッシュキー

  • widthformat クエリで画像を変換する場合、キャッシュキーを統一
  • アップスケール抑制(原寸以上禁止)をデフォルトに
  • DPR/フォーマット交渉を導入するなら、キャッシュ断片化を把握する

関連: CDNエッジリサイズの落とし穴 2025 — アップスケール/キャッシュ/画質の三角形, エッジ時代の画像配信最適化 CDN 設計 2025

計測とガードレール(現場運用)

  • RUM で INP/LCP を収集(web-vitals)。入力直後の Long Task を監視
  • デプロイごとに p75 を比較し、priority 乱用や sizes 逸脱を検知
  • CI のスナップショットで JSON-LD/構造化データと合わせて回帰検出(サイト全体の健全性)

簡易 RUM フック例:

import { onINP, onLCP } from 'web-vitals/attribution';

onINP((m) => fetch('/rum', { method: 'POST', body: JSON.stringify({ name: m.name, value: m.value }) }));
onLCP((m) => fetch('/rum', { method: 'POST', body: JSON.stringify({ name: m.name, value: m.value }) }));

ケーススタディ(短編)

事例1: LP ヒーロー + 折り返し直下ギャラリー

  • 症状: スクロール直後に 16 枚のサムネが一斉ロード → INP p75 が 320→380ms
  • 対策: rootMargin: '300px 0px' で段階ロード、sizes を実寸に修正、初期化を requestIdleCallback 後へ
  • 結果: INP p75 が 380→250ms、LCP は 3% 改善

事例2: 記事本文の図版

  • 症状: sizes 未設定で過配信、デコードが重くスクロール直後に引っかかる
  • 対策: コンテナ幅から sizes を算出、decoding="async" へ統一
  • 結果: 画像デコード時間 35% 短縮、INP p75 が 40ms 改善

FAQ

Q. priorityfetchPriority="high" は両方必要?

A. 実装的には併用して問題ありませんが、対象は「ヒーロー1枚」に限定してください。

Q. Blur プレースホルダーは使うべき?

A. CLS 防止には有効ですが、INP は直接改善しません。軽い実装に留めましょう。

Q. fill と固定幅、どちらを選ぶ?

A. レイアウトが可変なら fill + aspect-ratio、固定なら width/height。いずれも sizes で実寸化します。

チェックリスト(配信用)

  • [ ] LCP 候補のみ priority/fetchPriority="high"/decoding="sync"
  • [ ] 非 LCP は loading="lazy" + decoding="async"
  • [ ] sizes はレイアウトと一致(過配信なし)
  • [ ] fill の場合は親に position: relativeaspect-ratio
  • [ ] 入力直後 300–500ms 窓に重い decode/初期化を置かない
  • [ ] RUM で INP/LCP の回帰を監視、p75 を主指標に

関連記事

Web

INP中心の画像配信最適化 2025 — decode/priority/スクリプト協調で体感を守る

LCPだけでは不十分。INPを悪化させない画像配信の設計原則とNext.js/ブラウザAPIでの実装手順を体系化。decode属性・fetchpriority・遅延読み込み・スクリプト協調まで。

基礎

画像のA/Bテスト設計 2025 — 画質・速度・CTRを同時に最適化

フォーマット/画質/サイズ/プレースホルダーの組み合わせを、LCP/INPとCTRで評価し、実運用に落とすテスト設計。

Web

画像の優先度設計とpreloadの最適解 2025

LCP候補の画像にfetchpriorityとpreloadを正しく適用。imagesrcset/sizesの使い分け、プレロードの落とし穴、INPを悪化させない実装までを実例で解説します。

圧縮

画像圧縮 完全戦略 2025 ─ 画質を守りつつ体感速度を最適化する実践ガイド

Core Web Vitals と実運用に効く最新の画像圧縮戦略を、用途別の具体的プリセット・コード・ワークフローで徹底解説。JPEG/PNG/WebP/AVIF の使い分け、ビルド/配信最適化、トラブル診断まで網羅。

圧縮

バッチ最適化パイプライン設計 INP/品質/スループットを両立 2025

画像の一括最適化を“壊さず速く”。INPを悪化させないUI配慮、非同期キュー、形式選択、検証の自動化まで、実運用で役立つ設計図を公開します。

Web

画像配信最適化 2025 — Priority Hints / Preload / HTTP/2 の実戦ガイド

LCP と CLS を犠牲にしない画像配信のベストプラクティス。Priority Hints、Preload、HTTP/2、適切なフォーマット戦略で検索トラフィックと体験を両立します。