🖼️

【Next.js】画像の表示は <Image> 一択。基本と preload の使い方

に公開

F

はじめに

Next.js には、画像の最適化を自動で行ってくれる <Image> コンポーネント が用意されています。公式ドキュメントでも、画像まわりは基本的にこのコンポーネントを使うことが推奨されています。
https://nextjs.org/docs/app/api-reference/components/image

では、なぜ素の <img> ではなく、わざわざ <Image> を使う必要があるのでしょうか?
この記事では、その理由としくみを掘り下げて解説していきます。

なぜ <img> ではなく <Image> を使うのか

next/image<Image> コンポーネントには、素の <img> にはない最適化が組み込まれています。代表的なものを挙げると以下です。

1. 画像フォーマットの自動変換

ブラウザが WebP などのモダン形式に対応していれば、JPEG/PNG から 自動的に軽量な形式に変換 して返してくれます。
結果として、ファイルサイズが小さくなり、ページの読み込みが速くなります。

2. 自動レスポンシブ対応(srcset / sizes

Next.js 側で良きに計らってくれて、画面幅に応じてちょうど良いサイズの画像を返してくれます。 CSS でメディアクエリごとに画像サイズをゴリゴリ調整しなくても、比率を保ったまま、自動的にサイズ調整 してくれます。

3. 自動 Lazy Loading(遅延読み込み)

ビューポート外の画像は、ユーザーがスクロールして近づくまで読み込まない Lazy Loading がデフォルトで有効になっています。

  • ページ表示直後のネットワーク負荷を減らす
  • 使われない画像を無駄に読み込まない

といったメリットがあります。

4. CLS(レイアウトシフト)の軽減

width / height、もしくは fill + 親要素の制約をしっかり指定することで、画像読み込み時のガタつき(CLS)を減らす ことができます。

5. キャッシュや CDN と一体になった最適化

Next.js の Image 最適化は、CDN やキャッシュ戦略とセットで設計されています。
一度生成した最適化済み画像をキャッシュすることで、二回目以降のアクセスを高速化 できます。

基本的な使い方

一番シンプルな例はこんな感じです。

import Image from "next/image";

export default function Profile() {
  return (
    <Image
      src="/images/profile.png"  // public ディレクトリ配下
      alt="サイト作者のプロフィール写真" // アクセシビリティのため必須
      width={400}                // 表示サイズ(px)
      height={400}
    />
  );
}

よく使う props ざっくり一覧

※型や細かい仕様は公式 API リファレンスを参照してください。 

src

画像のパス/URL。
リモート画像を使うときは next.config.js の images.remotePatterns などで 許可するドメイン を指定する必要があります。 

alt

画像の内容を説明するテキスト。画面読み上げや、画像が読み込めないときに使われます。

width / height

画像の表示サイズ(px)。明示的に指定しておくと、画像の読み込み前でも枠が確保され、CLS を防ぎやすくなります。

fill

親要素を埋める形で画像を伸縮させたいときに使うフラグ。

<div className="relative w-full aspect-[16/9]">
  <Image
    src="/images/hero.jpg"
    alt="ヒーローイメージ"
    fill
    style={{ objectFit: "cover" }}
    priority
  />
</div>

fill を使うときは、親要素に position: relative などで位置指定と、縦横比(aspect-ratio など) を持たせるのが定番パターンです。

sizes

レスポンシブ時の「実際の表示幅」をブラウザへ伝えるためのヒント。

<Image
  src="/images/thumbnail.jpg"
  alt="記事のサムネイル"
  width={800}
  height={600}
  sizes="(max-width: 768px) 100vw, 33vw"
/>

簡単に言うと:

  • スマホ(768px 以下)なら画面幅いっぱい(100vw)
  • それより大きければ 1/3 幅(33vw)という意味になります。

placeholder / blurDataURL

placeholder="blur" を指定すると、画像が読み込まれるまで ぼかし画像 を表示できます。
blurDataURL には小さな base64 画像を指定します。以下のサイトで作成できます。
https://blurred.dev/

<Image
  src="/images/profile.png"
  alt="プロフィール画像"
  width={400}
  height={400}
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,...."
/>

ローディング中の「チラつき」が気になるヒーロー画像や、プロフィールアイコンなどに使うと、体感がけっこう変わります。

Next.js 16 以降は priority ではなく preload

Next.js 16 以降では、画像の優先度を指定するための priority は 非推奨(deprecated) になり、代わりに preload が追加されています。 

  • 旧: priority を付けると、その画像は「LCP 候補」としてプリロード + eager ロードされる
  • 新: preload を使って、プリロードする画像を明示する

つまり、「この画像はファーストビューのキービジュアルなので最優先で読み込んでほしい」という場合に使うのが preload です。

ヒーロー画像にだけ preload を付ける

ファーストビューの大きな画像(LCP になりやすい画像)だけ、preload を付けるのが基本パターンで、preload + loading="eager" + fetchPriority="high"の3点セットを入れると他の画像よりも優先的に読み込ませることができます。

  • preload …… 先にダウンロードを始める
  • loading="eager" …… すぐに読み込む
  • fetchPriority="high" …… ネットワーク的な優先度を上げる
import Image from "next/image";

export default function Hero() {
  return (
    <section className="relative w-full aspect-[16/9] overflow-hidden">
      <Image
        src="/hero.jpg"
        alt="サービスのキービジュアル"
        fill
        // 重要な画像なのでプリロード + eager ロード
        preload
        loading="eager"
        fetchPriority="high"
        style={{ objectFit: "cover" }}
      />
      <div className="absolute inset-0 flex items-center justify-center">
        <h1 className="text-3xl text-white font-bold drop-shadow-lg">
          サービス名が入る
        </h1>
      </div>
    </section>
  );
}

まとめ

  • <Image> を使うと、フォーマット変換・レスポンシブ・遅延読み込み などの画像最適化が自動で効く
  • Next.js 16 以降は priority非推奨 になったので、新しく書くコードでは preload を使う
  • ヒーロー画像など 一番最初に見せたい大きな画像 には
    preload + loading="eager" + fetchPriority="high" で「最優先読み込み」にする
  • それ以外の画像は、基本的にデフォルトの Lazy(loading="lazy")に任せて OK

最初から全部を完璧に使いこなそうとしなくても大丈夫です。
まずは「画像は <img> ではなく <Image> を使う」「ヒーロー画像だけ preload を付ける」くらいから始めてみて、少しずつ他のページにも広げていくと理解もしやすいと思います 🙌

関連記事:
📘 【Next.js】リンクは<Link>にする理由と基本の書き方
📘 【Next.js】動的ルートへのリンクは<Link>でこう書く
📘 【Next.js】layout.tsxの基本。共通レイアウトはここでまとめる

GitHubで編集を提案

Discussion