Edge ランタイムと Node.js ランタイム
Next.js におけるランタイムとは、コードの実行中に利用可能なライブラリ、API、および一般的な機能のセットを指します。
サーバーサイドでは、アプリケーションコードの一部をレンダリングできる2つのランタイムがあります:
- Node.js ランタイム(デフォルト): すべての Node.js API と互換性のあるエコシステムパッケージにアクセス可能
- Edge ランタイム: Web API をベースにしています
ランタイムの違い
ランタイムを選択する際には多くの考慮事項があります。この表では主要な違いを一目で確認できます。より詳細な分析が必要な場合は、以下のセクションを参照してください。
Node | Serverless | Edge | |
---|---|---|---|
コールドブート | / | 通常 | 低 |
HTTP ストリーミング | 可 | 可 | 可 |
I/O | 全 | 全 | fetch のみ |
スケーラビリティ | / | 高 | 最高 |
セキュリティ | 通常 | 高 | 高 |
レイテンシ | 通常 | 低 | 最低 |
npm パッケージ | 全 | 全 | 限定的なサブセット |
静的レンダリング | 可 | 可 | 不可 |
動的レンダリング | 可 | 可 | 可 |
fetch を使用したデータ再検証 | 可 | 可 | 可 |
Edge ランタイム
Next.js の軽量な Edge ランタイムは、利用可能な Node.js API のサブセットです。
Edge ランタイムは、低レイテンシで動的かつパーソナライズされたコンテンツを配信する必要がある場合に最適です。Edge ランタイムの速度はリソースの最小限の使用によるものですが、多くのシナリオでは制限となる可能性があります。
例えば、Edge ランタイムで実行されるコードは Vercel 上では 1 MB から 4 MB を超えることはできません。この制限にはインポートされたパッケージ、フォント、ファイルが含まれ、デプロイインフラストラクチャによって異なります。さらに、Edge ランタイムはすべての Node.js API をサポートしていないため、一部の npm
パッケージが動作しない可能性があります。例えば「Module not found: Can't resolve 'fs'」といったエラーが発生する場合があります。これらの API やパッケージを使用する必要がある場合は、Node.js ランタイムの使用を推奨します。
Node.js ランタイム
Node.js ランタイムを使用すると、すべての Node.js API とそれらに依存するすべての npm パッケージにアクセスできます。ただし、Edge ランタイムを使用したルートほど起動は高速ではありません。
Next.js アプリケーションを Node.js サーバーにデプロイする場合、インフラストラクチャの管理、スケーリング、設定が必要になります。あるいは、Vercel のようなサーバーレスプラットフォームに Next.js アプリケーションをデプロイすることも検討できます。これにより、これらの作業を任せることができます。
サーバーレス Node.js
サーバーレスは、Edge ランタイムよりも複雑な計算負荷を処理できるスケーラブルなソリューションが必要な場合に最適です。例えば Vercel の Serverless Functions では、インポートされたパッケージ、フォント、ファイルを含む全体のコードサイズは 50MB まで可能です。
Edge を使用したルートと比較した場合の欠点は、Serverless Functions がリクエストの処理を開始するまでに数百ミリ秒の起動時間がかかる可能性があることです。サイトのトラフィック量によっては、関数が頻繁に「ウォーム」状態にならないため、この現象が頻繁に発生する可能性があります。
使用例
セグメントごとのランタイムオプション
Next.js アプリケーションでは、個々のルートセグメントに対してランタイムを指定できます。これを行うには、runtime
という変数を宣言してエクスポートします。変数は文字列でなければならず、値は 'nodejs'
または 'edge'
ランタイムのいずれかでなければなりません。
以下の例は、'edge'
の値を指定して runtime
をエクスポートするページルートセグメントを示しています:
export const runtime = 'edge' // 'nodejs' (デフォルト) | 'edge'
export const runtime = 'edge' // 'nodejs' (デフォルト) | 'edge'
レイアウトレベルで runtime
を定義することも可能で、これによりレイアウト配下のすべてのルートが Edge ランタイムで実行されます:
export const runtime = 'edge' // 'nodejs' (デフォルト) | 'edge'
export const runtime = 'edge' // 'nodejs' (デフォルト) | 'edge'
セグメントのランタイムが設定されていない場合、デフォルトの nodejs
ランタイムが使用されます。Node.js ランタイムから変更する予定がない場合は、runtime
オプションを使用する必要はありません。
利用可能な API の完全なリストについては、Node.js ドキュメント と Edge ドキュメント を参照してください。どちらのランタイムも、デプロイインフラストラクチャに応じて ストリーミング をサポートできます。