12k
All articles

Next.jsにおける画像最適化によるパフォーマンス向上の方法

Next.jsの組み込みコンポーネント、カスタムローダー、CDN連携で画像を最適化し、Core Web Vitalsの改善、LCP短縮、レイアウトシフト解消を実現する。

OpenReplay Team
OpenReplay Team
Next.jsにおける画像最適化によるパフォーマンス向上の方法

画像はWebページ全体のサイズの50〜70%を占めることが多く、Largest Contentful Paint(LCP)やCumulative Layout Shift(CLS)といったCore Web Vitalsの指標に直接影響を与えます。不適切な画像処理は、JavaScriptが完璧に最適化されていても、Lighthouseスコアを低下させ、直帰率を上昇させ、SEOランキングを損なう可能性があります。

このガイドでは、組み込みのnext/imageコンポーネントを使用したNext.jsの画像最適化について、基本的な実装から高度なCDN統合とキャッシング戦略まで解説します。パフォーマンス指標とユーザー体験の両方を改善する、レスポンシブで高速読み込みの画像を配信する方法を学びます。

重要なポイント

  • next/imageコンポーネントは、画像を自動的にWebPやAVIFなどの最新フォーマットに変換し、ファイルサイズを25〜35%削減します
  • 適切な画像最適化により、LCPを50%改善し、帯域幅コストを60%削減できます
  • ファーストビュー画像にpriorityプロパティを使用し、レスポンシブサイズを設定することで、レイアウトシフトを防止できます
  • カスタムローダーを使用することで、高トラフィックアプリケーション向けの専門的な画像CDNとの統合が可能になります

next/imageコンポーネントがパフォーマンスに重要な理由

next/imageコンポーネントは、単なるHTMLの<img>タグのラッパーではありません。現代的な画像配信の重労働を処理する自動最適化パイプラインです。

コアパフォーマンス機能

自動フォーマット変換: Next.jsは、ブラウザがサポートしている場合にWebPおよびAVIFフォーマットを提供し、品質を損なうことなくJPEG/PNGと比較してファイルサイズを25〜35%削減します。

レスポンシブ画像生成: コンポーネントは、ビルド時またはオンデマンドで複数の画像サイズを作成し、モバイルユーザーがデスクトップサイズの画像をダウンロードしないようにします。

組み込みの遅延読み込み: ファーストビュー以下の画像は、ユーザーがスクロールして近づいたときにのみ読み込まれ、初期ページの重量を削減し、First Contentful Paint(FCP)を改善します。

レイアウトシフトの防止: widthとheightプロパティ(またはfillプロパティ)を必須とすることで、コンポーネントは画像が読み込まれる前にスペースを確保し、CLS問題を排除します。

基本的な実装と必須プロパティ

80%のユースケースをカバーするシンプルな実装から始めましょう:

import Image from 'next/image'

export default function Hero() {
  return (
    <Image
      src="/hero-banner.jpg"
      alt="Product showcase"
      width={1200}
      height={600}
      priority // LCP最適化のため即座に読み込む
    />
  )
}

主要なプロパティを使用するタイミング

priority: LCPに影響を与えるファーストビュー画像に追加します。遅延読み込みを無効にし、プリロードリンクを追加します。控えめに使用してください—ページあたり1〜2枚の重要な画像のみに使用します。

sizes: レスポンシブ画像に不可欠です。ビューポート幅に基づいてどの画像サイズをダウンロードするかをブラウザに指示します:

<Image
  src="/product.jpg"
  alt="Product"
  width={800}
  height={600}
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 800px"
/>

placeholder=“blur”: メイン画像の読み込み中に低品質のプレースホルダーを表示します。静的インポートの場合、Next.jsはblurDataURLを自動的に生成します:

import heroImage from '@/public/hero.jpg'

<Image
  src={heroImage}
  alt="Hero"
  placeholder="blur"
  // 静的インポートの場合、blurDataURLは自動生成されます
/>

remotePatternsを使用したリモート画像の設定

外部ソースからの画像の場合、next.config.jsremotePatternsを設定します(古いdomains設定は非推奨です):

// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'cdn.example.com',
        pathname: '/images/**',
      },
    ],
  },
}

このセキュリティ機能は、特定の外部ソースを許可しながら、悪意のある画像リクエストを防止します。

CDNとカスタムローダーによる高度な最適化

高トラフィックアプリケーションの場合、カスタムローダーを使用してCloudinaryやImgixなどの専門的な画像CDNを統合します:

// lib/imageLoader.js
export default function cloudinaryLoader({ src, width, quality }) {
  const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
  return `https://res.cloudinary.com/demo/image/upload/${params.join(',')}/${src}`
}

// コンポーネントでの使用
<Image
  loader={cloudinaryLoader}
  src="product.jpg"
  alt="Product"
  width={400}
  height={300}
/>

最適なパフォーマンスのためのキャッシング戦略

Next.jsはデフォルトで積極的なキャッシュヘッダーを設定します:

Cache-Control: public, max-age=31536000, immutable

動的コンテンツの場合、next.config.jsでこれらを上書きします:

module.exports = {
  async headers() {
    return [
      {
        source: '/_next/image(.*)',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=86400, stale-while-revalidate=604800',
          },
        ],
      },
    ]
  },
}

本番環境のベストプラクティス

実データで影響を測定する: LighthouseとWebPageTestを使用してLCPの改善を追跡します。適切に最適化されたヒーロー画像は、LCPを1〜2秒削減できます。

品質とファイルサイズのバランスを取る: 開始点としてquality={75}を設定します。視覚的品質とファイルサイズの削減をテストしてください—100から75に下げると、視覚的影響を最小限に抑えながら40%節約できることがよくあります。

異なる画像タイプを適切に処理する: SVGやすでに最適化されたアセットにはunoptimizedを使用します:

<Image
  src="/logo.svg"
  alt="Logo"
  width={200}
  height={50}
  unoptimized
/>

型安全性のためのTypeScript: 自動的な寸法検出と型チェックのために画像をインポートします:

import type { StaticImageData } from 'next/image'
import productImage from '@/public/product.jpg'

interface ProductCardProps {
  image: StaticImageData
  alt: string
}

よくあるトラブルシューティング問題

“Invalid src prop”エラー: リモートドメインがremotePatternsで設定されているか、カスタムローダーを使用していることを確認してください。

高DPIディスプレイでの画像のぼやけ: ソース画像が表示サイズの少なくとも2倍であることを確認し、70未満の積極的な品質設定を避けてください。

ビルド時間の増加: 数百枚の画像があるサイトの場合、ビルド時処理の代わりにオンデマンド最適化を検討するか、外部サービスを使用したカスタムローダーを実装してください。

まとめ

next/imageコンポーネントを通じたNext.jsの画像最適化は、最小限の設定で即座にパフォーマンスの向上を提供します。基本から始めましょう—適切なサイジング、遅延読み込み、フォーマット変換—その後、トラフィックが増加するにつれてCDN統合やカスタムローダーなどの高度な技術を重ねていきます。

重要なのは、実世界での影響を測定することです:適切に最適化された画像は、LCPを50%改善し、帯域幅コストを60%削減し、Core Web Vitalsスコアを大幅に向上させることができます。まずファーストビュー画像に焦点を当て、その後、画像パイプラインの残りを体系的に最適化していきましょう。

よくある質問

任意のドメインからの外部画像でnext/imageを使用できますか?

いいえ、セキュリティのためにnext.config.jsでremotePatternsを使用して許可されたドメインを設定する必要があります。これにより、悪意のある攻撃者がアプリケーションを画像プロキシとして使用することを防ぎます。カスタムローダーを使用してこれをバイパスすることもできます。

Retinaディスプレイで画像がぼやけるのはなぜですか?

高DPI画面の場合、ソース画像は表示サイズの少なくとも2倍である必要があります。また、品質設定が低すぎないか確認してください。通常、品質75〜85がファイルサイズと視覚的明瞭さの最適なバランスを提供します。

すべての重要な画像にpriorityを使用すべきですか?

いいえ、priorityはLCPに影響を与える1〜2枚の重要なファーストビュー画像にのみ使用してください。過度に使用すると遅延読み込みの目的が損なわれ、同時に多くの画像を読み込むことで実際にパフォーマンスを低下させる可能性があります。

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.