この記事の要点
next/imageは、サイズの最適化・レイアウトずれの防止・遅延読み込みをまとめて引き受ける。importした画像ならwidthとheightは自動。外部 URL の画像では自分で指定する。- 外部の画像を使うには
images.remotePatternsでの許可が必要。ここはできるだけ具体的に書く。 - バージョン 16 で画像の既定値がいくつか変わった。
qualityは75のみ、キャッシュ最小時間は 4 時間。 next/fontはフォントを自前で配信する。Google Fonts でもブラウザから外部への通信は発生しない。
表示速度の指標で真っ先に問題になるのが画像とフォントです。どちらも「大きなファイルが、必要になる前に、間違ったサイズで読み込まれる」ことで遅くなります。Next.js はこの 2 つに専用の仕組みを持っており、使うだけで大半の問題が消えます。
1next/image が引き受けること
| 課題 | next/image の対応 |
|---|---|
| 大きすぎる画像を配信してしまう | 端末に合ったサイズを生成し、WebP などの形式で返す |
| 読み込み完了時に画面が飛ぶ | 縦横比を先に確保してレイアウトのずれを防ぐ |
| 画面外の画像まで読み込む | ブラウザ標準の遅延読み込みを使う |
| 外部サーバーの画像を最適化できない | 許可した配信元の画像を実行時に最適化する |
2ローカル画像
プロジェクト直下の public に置いたファイルは、/ 始まりのパスで参照できます。この場合は width と height を自分で書きます。
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/profile.png"
alt="著者の写真"
width={500}
height={500}
/>
)
}
ファイルを import すると、ビルド時に実寸が分かるためサイズ指定が不要になります。ぼかしのプレースホルダ用データも自動で用意されます。
import Image from 'next/image'
import ProfileImage from './profile.png'
export default function Page() {
return (
<Image
src={ProfileImage}
alt="著者の写真"
placeholder="blur" // 読み込み中はぼかし表示
/>
)
}
ファイル名が実行時にしか決まらない場合は、サーバーコンポーネントの中で動的 import() を使えば同じ利点を得られます。ただしパスには固定の前置きが必要で、その配下のファイルはすべてバンドルに含まれる点に注意してください。
3外部サーバーの画像
URL を直接渡す場合、ビルド時にはファイルを読めないため width と height が必須です。親要素いっぱいに広げたい場合は fill を使います。
加えて、配信元を明示的に許可する必要があります。任意の URL を最適化できてしまうと、自分のサーバーが第三者の画像変換に使われてしまうためです。
// next.config.ts
import type { NextConfig } from 'next'
const config: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3.amazonaws.com',
port: '',
pathname: '/my-bucket/**',
search: '',
},
],
},
}
export default config
ホスト名だけで広く開けるのではなく、pathname まで絞るのが推奨です。なお、以前使われていた images.domains は非推奨になりました。remotePatterns に置き換えてください。
4バージョン 16 で変わった既定値
画像まわりは既定値の変更が多く、古い記事のまま設定すると挙動が変わります。
| 設定 | 以前 | バージョン 16 | 影響 |
|---|---|---|---|
minimumCacheTTL | 60 秒 | 4 時間 | 再生成の頻度が下がり、負荷とコストが減る |
qualities | すべて許可 | [75] のみ | 他の値を渡すと最も近い値に丸められる |
imageSizes | 16 を含む | 16 を除外 | srcset が短くなる |
maximumRedirects | 無制限 | 3 回 | リダイレクトの多い配信元で失敗しうる |
| ローカル IP | 許可 | 既定で拒否 | 社内ネットワーク配信では明示的な許可が必要 |
| クエリ付きローカル画像 | そのまま可 | localPatterns が必要 | /img.png?v=1 形式が 400 になる |
とくに quality を 90 などで指定していた場合、警告なく 75 に丸められます。意図した画質が必要なら、設定側で許可する値を列挙してください。
// next.config.ts
const config = {
images: {
qualities: [50, 75, 100],
},
}
5フォントの自前配信
next/font は、指定したフォントをビルド時に取り込み、自サイトから配信します。ブラウザから Google のサーバーへリクエストが飛ばないため、表示の安定とプライバシーの両面で有利です。
// app/layout.tsx
import { Geist } from 'next/font/google'
const geist = Geist({
subsets: ['latin'],
})
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="ja" className={geist.className}>
<body>{children}</body>
</html>
)
}
フォントは使ったコンポーネントの範囲に効きます。サイト全体に適用したい場合はルートレイアウトで指定します。
可変フォント(バリアブルフォント)が使える場合はそちらが推奨されます。太さごとにファイルを持たずに済むためです。可変フォントでない場合は weight の指定が必要になります。
import { Roboto } from 'next/font/google'
const roboto = Roboto({
weight: '400',
subsets: ['latin'],
})
6ローカルのフォントファイル
手元の woff2 を使う場合は next/font/local です。パスは、その関数を呼び出しているファイルからの相対で解決されます。
import localFont from 'next/font/local'
const myFont = localFont({
src: './my-font.woff2',
})
同じ書体で太さや斜体を使い分けるなら、配列で渡します。
const roboto = localFont({
src: [
{ path: './Roboto-Regular.woff2', weight: '400', style: 'normal' },
{ path: './Roboto-Italic.woff2', weight: '400', style: 'italic' },
{ path: './Roboto-Bold.woff2', weight: '700', style: 'normal' },
],
})
7つまずきやすいところ
- 外部画像が表示されない:
remotePatternsに登録されていません。エラーメッセージにホスト名が出ます。 width/heightが必須と怒られる:外部 URL では自動判定できません。fillを使う場合は親要素に位置指定が必要です。- 画質が変わった:バージョン 16 の
qualities既定値によって丸められています。 altを空にする:装飾目的なら空文字が正解ですが、内容を伝える画像には必ず説明を入れます。- 日本語フォントを丸ごと読み込む:欧文と違い、日本語のフォントはファイルが大きくなります。本文に使う場合はサブセット化や、システムフォントとの併用を検討してください。
アプリの中身が仕上がったら、最後は本番環境へ出す工程です。
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38