# Vercel 画像最適化ガイド：next/imageでCore Web Vitalsを上げ、請求を跳ねさせない

> Vercel公式に忠実な画像最適化ガイド。next/imageによるAVIF/WebP変換とCDNキャッシュ、remotePatterns/localPatternsの設定、キャッシュキー（q/w/url/Accept）と31日保持・minimumCacheTTL、_next/imageと_vercel/imageのURL形式、変換課金（MISS/STALE）の仕組みと『最適化すべき画像/すべきでない画像』の線引きでコストを抑える方法を実コードで解説します。

- 公開日: 2026-06-28
- 著者: 友田 陽大
- タグ: Vercel, Next.js, パフォーマンス, コスト最適化, フロントエンド, TypeScript, ISR
- URL: https://tomodahinata.com/blog/vercel-image-optimization-next-image-cost-performance-guide
- カテゴリ: Vercel 本番運用
- 総合ガイド: https://tomodahinata.com/blog/vercel-production-platform-guide

## 要点

- Vercelの画像最適化はnext/image（やAstro/Nuxtの同等コンポーネント）が使う変換パイプライン。元画像をAVIF/WebPに動的変換し、デバイス幅に合わせてリサイズしてCDNにキャッシュする。LCP改善とFast Data Transfer削減に直結する
- キャッシュキーはProject ID・q（品質1-100）・w（幅）・url（ローカルはコンテンツハッシュ）・Accept ヘッダ。ローカル画像はCDNで最大31日、リモートは上流のCache-Control max-ageかminimumCacheTTL（既定3600秒）の大きい方
- 課金は変換（MISS/STALE時のtransformation＋cache write）とcache read、Fast Data Transfer、Edge Request。だから『不要な画像を最適化しない』『品質・幅のバリエーションを絞る』『キャッシュを効かせる』がコスト最適化の核
- 最適化すべきでない画像：10KB未満のアイコン/サムネイル、GIF等のアニメ、SVG、頻繁に変わる画像。これらはunoptimizedで素通しし、変換クォータを無駄に使わない
- remotePatterns/localPatternsで最適化を許可するソースを限定し、外部画像は乱用防止にpathnameへアカウントIDを含める。再デプロイではキャッシュは無効化されない（手動/プログラムでpurge）

---

画像は、Webページで**最も重く・最も LCP に効く**要素です。最適化すれば Core Web Vitals が上がり、SEO と離脱率が改善します。一方、使い方を誤ると**変換課金で請求が跳ねます**。この2つを両立させるのが Vercel の画像最適化の勘所です。

この記事は [Vercel Image Optimization](https://vercel.com/docs/image-optimization) の公式仕様に忠実に、`next/image` の使い方とコスト最適化をまとめます。全体像は [Vercel 本番運用ガイド](/blog/vercel-production-platform-guide)、コストは [Active CPU 最適化](/blog/vercel-cost-active-cpu-pricing-optimization-guide) を参照してください。

---

## 仕組み：動的変換 → CDN キャッシュ

`next/image`（Astro/Nuxt も同等コンポーネント）を使うと、Vercel が**元画像を動的に最適化**します。

1. **`img` 素のタグ**を使うと最適化は**バイパス**され、元画像がそのまま配信される。
2. **`Image` コンポーネント**を使うと、Vercel の最適化パイプラインに乗る——AVIF/WebP への変換、デバイス幅に合わせたリサイズ、そして CDN キャッシュ。
3. キャッシュ状態：
   - **HIT**：キャッシュから配信（変換なし）
   - **MISS**：変換 → キャッシュ → 配信（**transformation ＋ cache write 課金**）
   - **STALE**：キャッシュ配信しつつ裏で再変換（同上）

```tsx
// app/page.tsx — next/image の基本
import Image from "next/image";
import hero from "@/public/hero.jpg"; // ローカル画像（ビルド時に解析）

export default function Page() {
  return (
    <Image
      src={hero}
      alt="製品のヒーロー画像"  // a11y：意味のある alt を必ず
      priority                  // LCP 画像は priority で先読み
      sizes="(max-width: 768px) 100vw, 50vw" // レスポンシブの幅指定
    />
  );
}
```

> **a11y の必須事項**：`alt` は飾りではありません。意味のある画像には内容を説明する `alt`、装飾画像には `alt=""` を。スクリーンリーダー利用者の体験と、画像 SEO の両方に効きます（[Web アクセシビリティ](/blog/react-nextjs-web-accessibility-wcag22-guide)）。

---

## 設定：remotePatterns / localPatterns で許可を絞る

どの画像ソースを最適化してよいかを `next.config.ts` で明示します。**無制限に許可しない**のがセキュリティとコストの両面で重要です。

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

const nextConfig: NextConfig = {
  images: {
    // ローカル（public 配下）
    localPatterns: [{ pathname: "/assets/images/**", search: "" }],

    // リモート（外部ホスト）
    remotePatterns: [
      {
        protocol: "https",
        hostname: "cdn.example.com",
        // 自分が所有しないホストは、乱用防止にアカウントID等を含める
        pathname: "/account123/**",
        search: "",
      },
    ],

    // 変換のバリエーションを絞る＝キャッシュ効率とコストに効く
    formats: ["image/avif", "image/webp"],
    qualities: [75], // 品質を1つに固定するとキャッシュキーが減る
  },
};

export default nextConfig;
```

> **乱用防止**：所有していない `hostname` を許可するときは、`pathname` にアカウント ID 等を含めて**自分のソースだけ**に限定します。ワイルドカードを広げすぎると、第三者経由の変換で課金を膨らまされるリスクがあります。

---

## キャッシュキーと保持期間

最適化画像は CDN にキャッシュされ、**キャッシュキー**が同じなら変換は再実行されません（＝課金されない）。キーは：

- Project ID
- `q`（品質 1〜100）
- `w`（幅 px）
- `url`（ローカルは**コンテンツハッシュ**、リモートは絶対URL）
- `Accept` ヘッダ（正規化）

保持期間：

| 種類 | 保持 |
|---|---|
| ローカル画像 | CDN で**最大31日** |
| リモート画像 | 上流の `Cache-Control` `max-age` か `minimumCacheTTL`（既定 **3600秒**）の**大きい方** |

> **再デプロイではキャッシュは無効化されません**。ローカル画像は「同名で中身を差し替えて再デプロイ」か、手動/プログラムでの[purge](https://vercel.com/docs/cdn-cache/purge)で無効化。リモート画像は一度キャッシュされると、期限切れか purge まで古い版が出続けます。「画像を差し替えたのに古いまま」はこれが原因。

### 変換 URL の形式

`Image` コンポーネントは `src` を最適化 URL に置換します。

- Next.js：`/_next/image?url={src}&w=3840&q=75`
- Nuxt/Astro 等：`/_vercel/image?url={src}&w=3840&q=75`

---

## コスト最適化：請求を跳ねさせない

画像最適化は「請求が増える主因」の常連です。効く順に。

### ① 最適化すべきでない画像を最適化しない

以下は `unoptimized` で**素通し**し、変換クォータを使いません。

- **10KB 未満のアイコン/サムネイル**（既に小さい）
- **GIF 等のアニメ画像**
- **SVG**（ベクター。最適化対象外）
- **頻繁に変わる画像**（キャッシュが効かず変換が走り続ける）

```tsx
// 小さいアイコンや SVG は最適化しない
<Image src="/icon.svg" alt="" width={24} height={24} unoptimized />
```

### ② バリエーションを絞る

キャッシュキーは `q`・`w`・`Accept` の組み合わせで増えます。`qualities` を1つ（例 75）に固定し、`sizes`/`deviceSizes` を必要な幅だけに絞ると、**ユニークな変換数＝課金が減り、HIT 率が上がります**。

### ③ キャッシュを効かせる

- リモート画像は `minimumCacheTTL` を伸ばして再変換を減らす（更新頻度とのトレードオフ）。
- 変換結果はデプロイ跨ぎで持続するので、不要な purge をしない。

### ④ 何を消費しているか見る

Observability の **Image Optimization Insights** で、変換数・cache read/write・Fast Data Transfer を確認し、重い箇所を特定します（[可観測性](/blog/vercel-observability-monitoring-speed-insights-log-drains-guide)）。

---

## いつ使う/使わない

| 最適化すべき | 最適化不要 |
|---|---|
| 製品写真・ヒーロー画像（大きい・高品質） | 10KB 未満のアイコン |
| ユーザーアップロード画像 | アニメ GIF |
| レスポンシブで幅が変わる画像 | SVG（ベクター） |
| 写真ポートフォリオ等、画像が主役 | 頻繁に変わる画像 |

> ユーザーアップロード画像は、保存を [Vercel Blob](/blog/vercel-storage-blob-edge-config-marketplace-guide)（client upload）にし、表示を `next/image` の `remotePatterns` で最適化、という組み合わせが定番です。

---

## 本番チェックリスト（画像最適化）

- [ ] 写真/ヒーロー/アップロード画像は **`next/image`** で最適化
- [ ] **`alt`** を意味に応じて設定（a11y・画像SEO）
- [ ] LCP 画像に **`priority`**、**`sizes`** でレスポンシブ
- [ ] **小アイコン/SVG/GIF/頻繁更新は `unoptimized`**
- [ ] `remotePatterns`/`localPatterns` で**ソースを限定**、外部は pathname を絞る
- [ ] `qualities`・幅の**バリエーションを絞る**（HIT 率↑・課金↓）
- [ ] 画像差し替え時は**キャッシュ無効化**（同名差し替え or purge）を理解
- [ ] Observability で**変換数・転送量を監視**

---

## まとめ

画像最適化は「速さ（CWV・SEO）」と「コスト」を**同時に**作る領域です。

1. **`next/image`** で AVIF/WebP 変換・レスポンシブ・CDN キャッシュ
2. キャッシュキー（`q`/`w`/`url`/`Accept`）と**保持期間**を理解
3. コストは **①不要画像を最適化しない ②バリエーションを絞る ③キャッシュを効かせる**
4. ソースは `remotePatterns` で限定、再デプロイでキャッシュは消えない
5. **Observability で消費を監視**し、計測 → 最適化

CWV を上げつつ画像コストを抑えるチューニングを、案件として承ります。本クラスタの起点は [Vercel 本番運用ガイド](/blog/vercel-production-platform-guide) です。

> 本記事は [Vercel Image Optimization](https://vercel.com/docs/image-optimization) 公式ドキュメント（2026年6月時点）に基づきます。仕様・課金・上限は更新されるため、本番採用時は公式で最新値を確認してください。
