Menu

メモリ使用量

アプリケーションが成長し、より多くの機能を持つようになると、ローカル開発や本番ビルドの際により多くのリソースを必要とする可能性があります。

Next.jsでメモリを最適化し、一般的なメモリ問題に対処するためのいくつかの戦略と手法を探ってみましょう。

依存関係の数を減らす

多数の依存関係を持つアプリケーションは、より多くのメモリを使用します。

バンドルアナライザーは、パフォーマンスとメモリ使用量を改善するために削除できる可能性のある大きな依存関係を調査するのに役立ちます。

experimental.webpackMemoryOptimizations を試す

v15.0.0以降、next.config.jsファイルにexperimental.webpackMemoryOptimizations: trueを追加することで、最大メモリ使用量を減らすWebpackの動作を変更できます。ただし、コンパイル時間が若干増加する可能性があります。

補足: この機能は現在、さらに多くのプロジェクトでテストするため実験的ですが、リスクは低いと考えられています。

next build--experimental-debug-memory-usage で実行

14.2.0以降、next build --experimental-debug-memory-usageを実行することで、ビルド中のメモリ使用量に関する情報(ヒープ使用量やガベージコレクション統計など)を継続的に出力するモードでビルドを実行できます。メモリ使用量が設定された制限に近づくと、ヒープスナップショットが自動的に取得されます。

補足: この機能は、カスタムWebpack設定がない限り自動的に有効になるWebpackビルドワーカーオプションと互換性がありません。

ヒーププロファイルを記録

メモリの問題を調査するために、Node.jsからヒーププロファイルを記録し、Chrome DevToolsで読み込んで、潜在的なメモリリークの原因を特定できます。

ターミナルで、Next.jsビルドを開始する際にNode.jsに--heap-profフラグを渡します:

node --heap-prof node_modules/next/dist/bin/next build

ビルド終了時に、Node.jsによって.heapprofileファイルが作成されます。

Chrome DevToolsで、メモリタブを開き、「プロファイルを読み込む」ボタンをクリックしてファイルを可視化できます。

ヒープのスナップショットを分析

インスペクターツールを使用して、アプリケーションのメモリ使用量を分析できます。

next buildまたはnext devコマンドを実行する際、コマンドの先頭にNODE_OPTIONS=--inspectを追加します。これにより、デフォルトポートでインスペクターエージェントが公開されます。 ユーザーコードが開始される前に中断する場合は、代わりに--inspect-brkを渡すことができます。プロセス実行中に、Chrome DevToolsなどのツールを使用してデバッグポートに接続し、保持されているメモリを確認するためにヒープのスナップショットを記録および分析できます。

14.2.0以降、next build--experimental-debug-memory-usageフラグを付けて実行することで、ヒープスナップショットの取得が容易になります。

このモードで実行中、プロセスにSIGUSR2シグナルを送信すると、いつでもヒープスナップショットが取得されます。

ヒープスナップショットはNext.jsアプリケーションのプロジェクトルートに保存され、Chrome DevToolsなどのヒープアナライザーで読み込んで保持されているメモリを確認できます。このモードは、Webpackビルドワーカーとまだ互換性がありません。

詳細については、ヒープスナップショットの記録と分析方法を参照してください。

Webpackビルドワーカー

Webpackビルドワーカーにより、別のNode.jsワーカー内でWebpackコンパイルを実行でき、ビルド中のアプリケーションのメモリ使用量を削減できます。

v14.1.0以降、アプリケーションにカスタムWebpack設定がない場合、このオプションはデフォルトで有効になります。

Next.jsの古いバージョンを使用している場合、またはカスタムWebpack設定がある場合は、next.config.js内にexperimental.webpackBuildWorker: trueを設定してこのオプションを有効にできます。

補足: この機能は、すべてのカスタムWebpackプラグインと互換性がない可能性があります。

Webpackキャッシュを無効化

Webpackキャッシュは、ビルドの速度を向上させるために、生成されたWebpackモジュールをメモリやディスクに保存します。これは パフォーマンスに役立ちますが、キャッシュデータを保存するためにアプリケーションのメモリ使用量も増加します。

カスタムWebpack設定をアプリケーションに追加することで、この動作を無効にできます:

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (
    config,
    { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
  ) => {
    if (config.cache && !dev) {
      config.cache = Object.freeze({
        type: 'memory',
      })
    }
    // 重要: 変更された設定を返します
    return config
  },
}
 
export default nextConfig

静的解析を無効化

型チェックとリンティングは、特に大規模なプロジェクトでは多くのメモリを必要とする可能性があります。 ただし、ほとんどのプロジェクトには、これらのタスクをすでに処理する専用のCIランナーがあります。 「型の妥当性の確認とリンティング」ステップでメモリ不足の問題が発生する場合、ビルド中にこれらのタスクを無効にできます:

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  eslint: {
    // 警告: これにより、プロジェクトにESLintエラーがあっても、本番ビルドを正常に完了できます。
    ignoreDuringBuilds: true,
  },
  typescript: {
    // !! 警告 !!
    // 危険です。プロジェクトに型エラーがあっても、本番ビルドを正常に完了できます。
    // !! 警告 !!
    ignoreBuildErrors: true,
  },
}
 
export default nextConfig

静的解析が完了する前にビルドを本番環境にデプロイすると、不具合のあるデプロイが発生する可能性があることに注意してください。 静的解析が完了した後にのみ、ビルドを本番環境に昇格させることを強くお勧めします。 Vercelにデプロイする場合は、ステージングデプロイメントのガイドを参照して、カスタムタスクが成功した後にビルドを本番環境に昇格させる方法を学べます。

ソースマップを無効化

ソースマップの生成は、ビルドプロセス中に追加のメモリを消費します。

Next.jsの設定にproductionBrowserSourceMaps: falseexperimental.serverSourceMaps: falseを追加することで、ソースマップの生成を無効にできます。

補足: 一部のプラグインがソースマップをオンにする可能性があり、無効にするにはカスタム設定が必要な場合があります。

Edgeメモリの問題

Next.js v14.1.3は、Edgeランタイム使用時のメモリ問題を修正しました。この問題が解決されたかを確認するため、このバージョン(またはそれ以降)に更新してください。