メモリ使用量
アプリケーションが成長して機能が豊富になるにつれて、ローカルでの開発や本番環境でのビルドの際に、より多くのリソースを求める可能性があります。
Next.jsにおける一般的なメモリ問題を解決し、メモリを最適化するための戦略や手法を探ってみましょう。
依存関係の数を減らす
多数の依存関係を持つアプリケーションは、より多くのメモリを使用します。
Bundle Analyzerを使用すると、パフォーマンスとメモリ消費を改善するために削除できるかもしれない大きな依存関係を調査することができます。
experimental.webpackMemoryOptimizations
を試す
v15.0.0
から、next.config.js
ファイルにexperimental.webpackMemoryOptimizations: true
を追加することで、Webpack内の動作を変更し、最大メモリ使用量を減らしますが、コンパイル時間が若干増加する可能性があります。
Good to know: この機能は現在実験的で、まずは複数のプロジェクトでテストが行われていますが、リスクは低いと考えられています。
--experimental-debug-memory-usage
オプションでnext build
を実行する
14.2.0
から、next build --experimental-debug-memory-usage
を実行することで、メモリ使用状況に関する情報をビルド中に継続的に出力するモードでビルドを実行できます。ヒープ使用量やガベージコレクションの統計情報が表示され、メモリ使用量が設定した制限に近づくと自動的にヒープスナップショットが取られます。
Good to know: この機能はカスタムWebpack設定がない限り自動的に有効なWebpackビルドワーカーオプションと互換性がありません。
ヒーププロファイルを記録する
メモリ問題を探すために、Node.jsからヒーププロファイルを記録し、それをChrome DevToolsに読み込んで、メモリリークの潜在的な原因を特定できます。
ターミナルで、Next.jsビルドを開始するときに、node --heap-prof
フラグをNode.jsに渡します:
node --heap-prof node_modules/next/dist/bin/next build
ビルド終了時に、Node.jsによって.heapprofile
ファイルが作成されます。
Chrome DevToolsで、メモリタブを開き、「Load Profile」ボタンをクリックしてファイルを可視化します。
ヒープのスナップショットを分析する
インスペクターツールを使用して、アプリケーションのメモリ使用状況を分析できます。
next build
またはnext dev
コマンドを実行する際に、コマンドの先頭にNODE_OPTIONS=--inspect
を追加します。これにより、デフォルトポートでインスペクターエージェントが公開されます。
ユーザーコードが実行される前に停止する場合は、代わりに--inspect-brk
を渡すことができます。プロセスが実行中の間、Chrome DevToolsのようなツールを使用して、デバッグポートに接続し、ヒープのスナップショットを記録して分析し、どのメモリが保持されているかを確認できます。
14.2.0
から、next build
を--experimental-debug-memory-usage
フラグで実行することもでき、ヒープスナップショットを簡単に取得できます。
このモードで実行中に、任意の時点でプロセスにSIGUSR2
シグナルを送信すると、プロセスはヒープスナップショットを取得します。
ヒープスナップショットは、Next.jsアプリケーションのプロジェクトrootに保存され、Chrome DevToolsのようなヒープアナライザーで読み込んで、どのメモリが保持されているかを確認できます。このモードはまだWebpackビルドワーカーと互換性がありません。
詳しくはヒープスナップショットの記録と分析方法をご覧ください。
Webpackビルドワーカー
Webpackビルドワーカーを使用すると、Webpackコンパイルを別のNode.jsワーカー内で実行でき、ビルド中のアプリケーションのメモリ使用量を削減できます。
このオプションは、v14.1.0
から、カスタムWebpack設定がない場合にデフォルトで有効になっています。
古いバージョンのNext.jsを使用している場合やカスタムWebpack設定を持っている場合は、next.config.js
内でexperimental.webpackBuildWorker: true
を設定することでこのオプションを有効にできます。
Good to know: この機能はすべてのカスタムWebpackプラグインと互換性がない場合があります。
Webpackキャッシュを無効にする
Webpackキャッシュは、生成されたWebpackモジュールをメモリおよび/またはディスクに保存して、ビルド速度を向上させます。これによりパフォーマンスが向上しますが、キャッシュデータを保存するためにアプリケーションのメモリ使用量も増加します。
この動作を無効にするには、アプリケーションにカスタムWebpack設定を追加します:
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (
config,
{ buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
) => {
if (config.cache && !dev) {
config.cache = Object.freeze({
type: 'memory',
})
}
// 重要:変更したconfigを返す
return config
},
}
export default nextConfig
静的解析を無効にする
型チェックやリントは、大規模なプロジェクトで特に多くのメモリを必要とすることがあります。 ただし、ほとんどのプロジェクトには、すでにこれらのタスクを処理する専用のCIランナーがあります。 「Linting and checking validity of types」ステップ中にメモリ不足の問題が発生する場合は、ビルド時にこれらのタスクを無効にすることができます:
/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: {
// 警告:ESLintエラーがある場合でも本番ビルドが成功します。
ignoreDuringBuilds: true,
},
typescript: {
// !! 警告 !!
// Typeエラーがある場合でも本番ビルドが成功するように危険を冒します。
// !! 警告 !!
ignoreBuildErrors: true,
},
}
export default nextConfig
これにより、型エラーやリントの問題が原因で不具合のあるデプロイが生じる可能性があることを心に留めておいてください。 静的解析が完了するまでは、本番環境へのビルドの昇格をお勧めします。 Vercelにデプロイする場合は、本番デプロイの昇格ガイドを確認して、カスタムタスクが成功した後にビルドを本番環境に昇格する方法を学んでください。
ソースマップを無効にする
ソースマップの生成には、ビルドプロセス中に追加のメモリが消費されます。
ソースマップの生成を無効にするには、Next.js設定にproductionBrowserSourceMaps: false
とexperimental.serverSourceMaps: false
を追加します。
Good to know: 一部のプラグインはソースマップをオンにし、無効にするためにカスタムの設定が必要な場合があります。
Edgeメモリの問題
Next.js v14.1.3
では、Edge runtimeの使用時に発生していたメモリ問題が修正されました。このバージョン以降に更新して、問題が解決するか確認してみてください。