【Next.js】next/imageで画像を最適化する

JavaScript

こんにちは、かつコーチです。

前回はVercelへのデプロイ方法を解説し、アプリを実際に公開できるようになりました。

公開したアプリが実際にユーザーに使われ始めると、次に気になってくるのが表示速度です。

特に画像は、対策をしないままだとページ全体の読み込み速度を大きく悪化させる要因になります。

今回は、Next.js標準のnext/imageを使って画像を最適化する方法を解説します。

next/imageとは?前提知識

画像最適化を自動化するコンポーネント

next/imageは、通常の<img>タグの代わりに使う、Next.js標準の画像コンポーネントです。

遅延読み込み(画面に表示されるタイミングまで画像の読み込みを遅らせる仕組み)や、デバイスに応じた画像サイズの自動生成、次世代フォーマットへの変換などを自動で行ってくれます。

素の<img>タグでこれらを自前実装しようとすると、それだけでかなりの工数がかかるため、標準機能として用意されているメリットは大きいです。

なぜ画像最適化が重要なのか

Webページの読み込み時間のうち、画像が占める割合は非常に大きいことが知られています。

検索エンジンの評価指標であるCore Web Vitals(ページの読み込み速度や視覚的な安定性を測る指標群)でも、画像の最適化はスコアに直結する項目です。

next/imageを使うだけでこれらの改善にかなりの部分アプローチできるため、パフォーマンスチューニングの最初の一手として非常にコスパが良い施策です。

基本の書き方・実装手順

手順1:基本的な使い方

// app/components/ProfileImage.tsx
import Image from "next/image";

export function ProfileImage() {
  return (
    <Image
      src="/profile.png"
      alt="プロフィール画像"
      width={200}
      height={200}
    />
  );
}

widthheightの指定は必須です。

事前にサイズを指定しておくことで、画像読み込み前後でレイアウトがガクッとずれるレイアウトシフトを防げます。

手順2:外部URLの画像を扱う設定

外部ドメインの画像を扱う場合は、next.config.tsにドメインを許可リストとして登録する必要があります。

// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "images.example.com",
      },
    ],
  },
};

export default nextConfig;

この設定なしに外部URLをsrcに渡すと、ビルドエラーになります。

任意の外部ドメインから無制限に画像を読み込めてしまうと、悪意あるURLの埋め込みにも繋がるため、明示的な許可リスト方式になっています。

手順3:親要素いっぱいに表示する(fill)

サイズが可変のカードUIなど、事前にwidth・heightを固定できない場面ではfillプロパティを使います。

// app/components/CardThumbnail.tsx
import Image from "next/image";

export function CardThumbnail({ src }: { src: string }) {
  return (
    <div style={{ position: "relative", width: "100%", aspectRatio: "16 / 9" }}>
      <Image
        src={src}
        alt="サムネイル画像"
        fill
        style={{ objectFit: "cover" }}
      />
    </div>
  );
}

fillを使う場合、親要素にposition: relativeを指定しておく必要があります。

手順4:優先度の高い画像を先読みする

ファーストビューに表示されるメイン画像には、priorityを指定して優先的に読み込ませます。

// app/page.tsx
import Image from "next/image";

export default function HomePage() {
  return (
    <Image
      src="/hero.jpg"
      alt="トップページのメインビジュアル"
      width={1200}
      height={600}
      priority
    />
  );
}

priorityを指定した画像は遅延読み込みの対象外になり、ページ読み込み直後から取得が始まります。

ファーストビューに表示される最重要画像だけに絞って使うのがポイントです。

つまずきやすい設定・注意点

next/imageはデフォルトでVercelの画像最適化APIを経由するため、Vercel以外の環境にデプロイする場合はloaderの設定が別途必要になることがあります。

自前のホスティング環境を使う予定がある場合は、公式ドキュメントのimages.loaderの項目を事前に確認しておくと安心です。

よくあるつまずきポイント・エラー対処

実際にハマった「remotePatterns」未設定エラー

私が実際につまずいた経験を1つ共有します。

CMSから取得した画像URLをそのままnext/imagesrcに渡したところ、次のエラーが表示されました。

Error: Invalid src prop on `next/image`, hostname "cms.example.com" is not configured under images in your `next.config.js`

❌ Before:remotePatternsに設定を追加せずCMSの画像URLをそのまま使う

<Image src="https://cms.example.com/uploads/thumbnail.jpg" alt="記事サムネイル" width={400} height={300} />

CMSの画像ドメインを許可リストに追加していなかったため、ローカル環境でこのエラーが繰り返し表示されました。

✅ After:next.config.tsにCMSのドメインを追加する

// next.config.ts
const nextConfig: NextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "cms.example.com",
      },
    ],
  },
};

設定を追加して開発サーバーを再起動したところ、正常に画像が表示されるようになりました。

CMSやSNSなど画像の取得元が複数ある場合は、最初にドメインを洗い出して一括でremotePatternsに登録しておくと、後からのエラー対応に振り回されずに済みます。

まとめ

この記事のポイント

  • next/imageは遅延読み込みやサイズ最適化を自動化してくれる、Next.js標準の画像コンポーネント
  • widthheightの指定はレイアウトシフト防止のために必須
  • 外部ドメインの画像はnext.config.tsremotePatternsで明示的に許可する必要がある
  • サイズが可変のUIにはfill、ファーストビューの主要画像にはpriorityを使う
  • Vercel以外の環境にデプロイする場合は、画像最適化のloader設定を事前に確認しておく

次に読むべき記事

認証・テスト・デプロイ・画像最適化と、実践的なNext.js開発の一通りの流れを押さえてきました。

次回は、これまでの内容を踏まえて、Next.js開発でよく出るエラーとその解決法をまとめて紹介します。

→ 次の記事:Next.jsでよく出るエラーと解決法まとめ

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