Dev Study
← 解説「next/image — 画像の最適化」に戻る

サンプルコードで身につける: next/image — 画像の最適化

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1最小の Image

public フォルダの画像を Image コンポーネントで表示する最小形です。src・alt・width・height の4つを渡すだけで、圧縮・形式変換・遅延読み込みが全部自動で効きます。

import Image from "next/image";

export default function Logo() {
  return (
    <Image
      src="/logo.png" // public/logo.png を指す
      alt="サイトのロゴ"
      width={120}
      height={40}
    />
  );
}
// この4つの指定だけで、圧縮・変換・遅延読み込みが自動になる。

2img タグと何が違うのか

同じ画像を img タグと Image で並べて、自動で得られるものを比べる例です。img では手作業だった圧縮・最適な形式への変換・遅延読み込みが、Image では書かなくても付いてくることが対比で分かります。

import Image from "next/image";

export default function Compare() {
  return (
    <div>
      {/* ただの img: 元ファイルがそのまま届く(3MB なら 3MB) */}
      <img src="/photo.jpg" alt="写真" width={400} height={300} />

      {/* Image: 自動で圧縮 + 軽い形式(WebPなど)に変換 +
          画面に入るまで読み込まない遅延読み込み付き */}
      <Image src="/photo.jpg" alt="写真" width={400} height={300} />
    </div>
  );
}
// 見た目は同じでも、転送されるデータ量が大きく違う。

3fill で親要素いっぱいに表示する

サイズが事前に決めにくいヒーロー画像などでは、width / height の代わりに fill を使って親要素に合わせます。sizes で画面幅ごとの表示幅を伝えると、端末に合った大きさの画像だけが配信されます。

import Image from "next/image";

export default function Hero() {
  return (
    // fill を使うときは親要素に position: relative が必要
    <div style={{ position: "relative", height: 400 }}>
      <Image
        src="/hero.jpg"
        alt="メインビジュアル"
        fill // 親要素いっぱいに広がる(width/height の代わり)
        style={{ objectFit: "cover" }}
        sizes="100vw" // 画面幅いっぱいで表示する、という事前情報
      />
    </div>
  );
}

4外部画像と remotePatterns の許可

CMS やストレージなど外部ドメインの画像は、next.config で許可してからでないと Image で表示できません。「外部画像でエラーが出たら remotePatterns」という、実務で必ず一度はぶつかるつまずきの対処をセットで示す例です。

// next.config.ts — 外部ドメインの画像は事前に許可が必要
const nextConfig = {
  images: {
    remotePatterns: [
      { protocol: "https", hostname: "images.example-cms.com" },
    ],
  },
};
export default nextConfig;

// ─────────────────────────────
// app/article/page.tsx — 許可したドメインの画像を使う
import Image from "next/image";

export default function ArticleImage() {
  return (
    <Image
      src="https://images.example-cms.com/cover.jpg"
      alt="記事のカバー画像"
      width={800}
      height={420}
    />
  );
}

5商品ギャラリーと priority

商品一覧のように画像が並ぶ画面での実務的な使い方です。基本は遅延読み込みに任せつつ、最初に目に入る画像だけ priority を付けて先に読み込ませる、という「見える画像は速く、見えない画像は後で」の使い分けを示します。

import Image from "next/image";

const products = [
  { id: 1, title: "スニーカー", image: "/products/sneaker.jpg" },
  { id: 2, title: "リュック", image: "/products/backpack.jpg" },
  { id: 3, title: "キャップ", image: "/products/cap.jpg" },
];

export default function ProductGallery() {
  return (
    <ul>
      {products.map((product, index) => (
        <li key={product.id}>
          <Image
            src={product.image}
            alt={product.title}
            width={300}
            height={300}
            priority={index === 0} // 最初の1枚だけ優先読み込み
          />
          <p>{product.title}</p>
        </li>
      ))}
    </ul>
  );
}