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/image
のplaceholder
は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: relative
とaspect-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最適化: 変換とキャッシュキー
width
やformat
クエリで画像を変換する場合、キャッシュキーを統一- アップスケール抑制(原寸以上禁止)をデフォルトに
- 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. priority
と fetchPriority="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: relative
とaspect-ratio
- [ ] 入力直後 300–500ms 窓に重い decode/初期化を置かない
- [ ] RUM で INP/LCP の回帰を監視、p75 を主指標に
関連記事
INP中心の画像配信最適化 2025 — decode/priority/スクリプト協調で体感を守る
LCPだけでは不十分。INPを悪化させない画像配信の設計原則とNext.js/ブラウザAPIでの実装手順を体系化。decode属性・fetchpriority・遅延読み込み・スクリプト協調まで。
画像のA/Bテスト設計 2025 — 画質・速度・CTRを同時に最適化
フォーマット/画質/サイズ/プレースホルダーの組み合わせを、LCP/INPとCTRで評価し、実運用に落とすテスト設計。
画像の優先度設計とpreloadの最適解 2025
LCP候補の画像にfetchpriorityとpreloadを正しく適用。imagesrcset/sizesの使い分け、プレロードの落とし穴、INPを悪化させない実装までを実例で解説します。
画像圧縮 完全戦略 2025 ─ 画質を守りつつ体感速度を最適化する実践ガイド
Core Web Vitals と実運用に効く最新の画像圧縮戦略を、用途別の具体的プリセット・コード・ワークフローで徹底解説。JPEG/PNG/WebP/AVIF の使い分け、ビルド/配信最適化、トラブル診断まで網羅。
バッチ最適化パイプライン設計 INP/品質/スループットを両立 2025
画像の一括最適化を“壊さず速く”。INPを悪化させないUI配慮、非同期キュー、形式選択、検証の自動化まで、実運用で役立つ設計図を公開します。
画像配信最適化 2025 — Priority Hints / Preload / HTTP/2 の実戦ガイド
LCP と CLS を犠牲にしない画像配信のベストプラクティス。Priority Hints、Preload、HTTP/2、適切なフォーマット戦略で検索トラフィックと体験を両立します。