コンテンツにスキップ

メモリ使用量

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

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

依存関係の数を減らす

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

バンドルアナライザーは、アプリケーション内の大きな依存関係を調査するのに役立ちます。これを取り除くことで、パフォーマンスとメモリ使用量を改善できる可能性があります。

experimental.webpackMemoryOptimizations を試す

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

知っておくと良いこと: この機能は現在、より多くのプロジェクトで最初にテストするための実験的なものですが、リスクは低いと考えられています。

--experimental-debug-memory-usage を付けて next build を実行する

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

知っておくと良いこと: この機能は、カスタム 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以降では、--experimental-debug-memory-usageフラグを指定してnext buildを実行することもでき、ヒープスナップショットの取得が容易になります。

このモードで実行している間は、いつでもプロセスにSIGUSR2シグナルを送信でき、プロセスはヒープスナップショットを取得します。

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

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

Webpackビルドワーカー

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

このオプションは、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',
      })
    }
    // Important: return the modified config
    return config
  },
}
 
export default nextConfig

静的解析を無効にする

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

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  eslint: {
    // Warning: This allows production builds to successfully complete even if
    // your project has ESLint errors.
    ignoreDuringBuilds: true,
  },
  typescript: {
    // !! WARN !!
    // Dangerously allow production builds to successfully complete even if
    // your project has type errors.
    // !! WARN !!
    ignoreBuildErrors: true,
  },
}
 
export default nextConfig

これにより、型エラーやリンティングの問題により、デプロイに障害が発生する可能性があることに注意してください。静的解析が完了した後でのみ、ビルドを本番環境に昇格させることを強くお勧めします。Vercelにデプロイする場合は、カスタムタスクが成功した後にビルドを本番環境に昇格させる方法については、ステージングデプロイメントのガイドを参照してください。

ソースマップを無効にする

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

productionBrowserSourceMaps: falseおよびexperimental.serverSourceMaps: falseをNext.js構成に追加することで、ソースマップの生成を無効にできます。

知っておくと良いこと: 一部のプラグインはソースマップをオンにする可能性があり、無効にするにはカスタム構成が必要になる場合があります。

Edgeメモリの問題

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