【Next.jsビルド】画像最適化(next/image)の落とし穴

目次

Next.jsのバージョン14.0.0で、静的サイト生成(SSG)のビルド方法が変わりました:

  1. 新しい方法:
    • next.config.jsファイルに"output": 'export'を追加します。
    • next buildコマンドを実行すると、outフォルダに静的ファイルが生成されます。
  2. 以前の方法:
    • next build && next exportコマンドを使用していました。

そもそもSSGとは?(Static Site Generation)

「静的サイト生成」

ウェブサイトのコンテンツを事前にビルド時に生成し、静的なHTMLファイルとして保存する方法です。ユーザーがページにアクセスする時、すでに生成されたHTMLを素早く提供できます。

SSG(静的サイト生成)プロセス ビルド時 サーバー 静的HTML、CSS、JS リクエスト時 ユーザー CDN/Webサーバー 1. 静的ファイルを生成 2. 静的ファイルを配信

画像最適化(next/image)の落とし穴

Next.js には公式で用意された画像最適化機能(next/image)があり、SSR (Server Side Rendering) や ISR (Incremental Static Regeneration) ではとても便利です。

しかし 動的な処理は基本的にビルド前に済ませる必要があるため下記の注意が必要です

⬇️

Next.js が提供しているサーバー側の最適化ロジックが動かない

< 注意 >

  1. サーバーが存在しないため動的最適化ができない
    本来、Next.js の画像最適化は、サーバー(Node.js)が裏で画像をリサイズ・圧縮などする仕組みです。静的サイトではサーバーが立ち上がらないので、この仕組みは使えません。
  2. unoptimized オプションを使う必要がある
    next.config.mjs(または next.config.js)で images: { unoptimized: true } とすると、<Image> コンポーネントは“素”の <img> タグとして扱われ、最適化なしでビルドされます。
  3. 独自ローダーの設定も可能
    完全に独自の外部サービスや CDN で画像を最適化する場合は、loader プロパティを使って処理先を指定できます。ただし、これも自前で最適化基盤を用意する必要があるため、プロジェクト規模によって検討してください。

SSG だと画像最適化できない問題への一般的な改善案

Next.js の SSG と 画像最適化 の流れ Step 1 next.config.js output: ‘export’ images: {{ unoptimized: true }} Step 2 npm run build 静的ファイル生成 Step 3 out/ ディレクトリ すべて静的化 Step 4 静的ホスティング ● 画像最適化で注意すべき点 1. 完全静的化では Next.js のサーバーが動かないため、 画像をオンデマンドで最適化できません。 2. <Image> コンポーネントをそのまま使う場合、 unoptimized: true を設定して静的化します。 3. より高性能な画像最適化が必要であれば、 独自ローダーや外部サービスの利用を検討しましょう。

out フォルダの中身

通常、out フォルダには以下のようなファイルやフォルダが生成されます。

  • index.html: 各ページの静的 HTML ファイル。pages/index.js がここに対応します。
  • _next/ フォルダ: この中には Next.js が最適化した JavaScript、CSS、画像ファイルなどが含まれています。ブラウザでキャッシュされるファイルです。
  • 各ページの HTML ファイル: ルートや動的なページも静的に生成されます(SSG を使用している場合)。

生成したファイル群をレンタルサーバー上で公開

1)next.config.js ファイルで適切な設定を行います

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  distDir: 'out',
  assetPrefix: 'https://siennahare23.sakura.ne.jp/nextjs-content/readmore',
  basePath: '/nextjs-content/readmore',
  trailingSlash: true,
}

module.exports = nextConfig
  • output: 'export': 静的ファイルを生成するための設定
  • distDir: 'out': ビルド出力先ディレクトリの指定
  • assetPrefix: 静的アセット(JS, CSS, 画像など)のURL prefix
  • basePath: アプリケーションのベースパス
    basePathは、Next.jsアプリケーションのすべてのルートの前に付加されるパスプレフィックスです。これは特に、サブディレクトリにアプリケーションをデプロイする場合に役立ちます。
  • trailingSlash: true: URLの末尾にスラッシュを追加

2)npm run build

package.json の scriptsが下記になっているか確認

"scripts": {
  "build": "next build"
}

3)サーバーへのアップロード

生成された out ディレクトリの内容を任意のサーバーのディレクトリにアップロード

  • index.html
  • _next ディレクトリ(JS, CSSファイルを含む)
  • その他の静的アセット(画像など)

下記はiframeでの読み込みました

<iframe 
  src="https://siennahare23.sakura.ne.jp/nextjs-content/readmore/readmore/index.html" 
  width="100%" 
  height="600px" 
  frameborder="0" 
  style="width: 100%; min-height: 600px;"
></iframe>

この記事を書いた人

目次