next/image の使い方。最適化の仕組みと Next.js 16 の既定
next/image は、画像を自分のサーバーで画面の幅に合わせた大きさと画質に変えてから配る部品です。
画像は、自分のサーバーを通って届く
next/image で出した画像の img は、元の画像を直接は指しません。実機で確かめた形です。
/_next/image?url=%2Fa.png&w=128&q=75
- Browser/_next/image へ取りに来る
元の画像の場所、幅(w)、画質(q)を付けて。
- Server許可された取得先か確かめる
外部の画像なら、remotePatterns に書いた相手か。違えば 400。
- Server幅と画質を変えて返す
画面に合った大きさにしてから配る。
大きさを変える仕事は自分のサーバーがします。自分でサーバーを動かしているなら、そのぶんの処理がかかります(自分のサーバーに置く)。
3つの書き方
| 書き方 | 要るもの | 寸法 |
|---|---|---|
| import した画像を src に渡す | なし | 自動で入る |
| public の画像を文字列で渡す | width と height | 自分で書く |
| 外部の URL を渡す | width と height、remotePatterns | 自分で書く |
いちばん書き忘れが無いのは、import して渡す形です。実機で、画像ファイルから寸法が読み取られて width と height が入りました。
import Image from 'next/image'
import photo from './photo.png'
export default function Page() {
return <Image src={photo} alt="" />
}
外部の画像は、取得先を next.config.ts の remotePatterns に書かないと、本番では画像が 400 になります(hostname のエラー)。
文字列で渡して width を書き忘れると、本番では型チェックもビルドも通ったまま、画面の幅いっぱいの画像として扱われます(width が無いエラー)。
sizes で、読み込む大きさが決まる
ブラウザは、img の候補(srcSet)と sizes から、読み込む版を選びます。同じ 1枚を幅 800 の画面で比べました。
| 書き方 | 付いた sizes | 読み込まれた版 |
|---|---|---|
| width={100} height={100} | なし | w=128 |
| width を書かない | 100vw | w=1080 |
fill で親の大きさに合わせるときも、sizes を書かないと実機では sizes="100vw" が付きました。実際に表示する幅を sizes に書きます。
Next.js 16 で変わった既定
公式のアップグレードガイドにある変更のうち、2つを実機で確かめました。
| 書いたもの | 設定なし | 直し方 |
|---|---|---|
| quality={90} | q=75 に丸められる(エラーは出ない) | images.qualities: [75, 90] |
| src="/a.png?v=1" | ページを描く段階でビルドが止まる | images.localPatterns に search を書く |
// next.config.ts
const nextConfig: NextConfig = {
images: {
qualities: [75, 90],
localPatterns: [{ pathname: '/**', search: '?v=1' }],
},
}
実機で、この設定なら q=90 になり、クエリ文字列付きの画像もビルドが通りました。
ガイドには、このほかに、画像を手元に残しておく時間の既定が 4時間になったこと、imageSizes の既定から 16 が外れたことなども書かれています。版を上げたら一度目を通してください(Next.js 16 で変わったこと)。
unoptimized は近道にしない
images.unoptimized: true にすると、変換も許可の確認も通らず、元の画像がそのまま届きます(この問題)。400 は消えますが、大きな画像は大きいまま配られます。
出典
- nextjs.org/docs/app/api-reference/components/image
- nextjs.org/docs/app/getting-started/images
- nextjs.org/docs/app/guides/upgrading/version-16
このページの内容は上記の一次情報を基準に書いています。個人ブログや二次情報を根拠にしていません。