[Next.js] Next.js 実行環境の性質まとめ
はじめに
独習JavaScript本を読んでいて、JavaScriptの実行環境の説明がされていた。
「WebブラウザとNode.jsの2つがあって、それらは別の特徴を持つよ」と説明されており、「Next.jsの場合はどういう仕組みになっているんだろう?」と気になったので、調べることにした。
以降Next.jsv15.3.4
のドキュメントを参照している。
前提1: JavaScriptの実行環境
ブラウザ環境、サーバサイド用環境に大別される。
ブラウザ環境
クライアント用の環境。
- ブラウザの構成: JavaScriptエンジン, DataStorage, User Interface (GUI)などから構成される。
- 構成要素(※):
UserInterface
,Data Storage
,Browser Engine
,Rendering Engine
,JavaScript Engine
,Network
,UI Background
- 構成要素(※):
- JavaScriptエンジン: JavaScriptコードを解析して実行するためのインタプリタ。
- V8 (Chrome), JavaScriptCore(Safari)など。
- ブラウザごとに、搭載されたエンジンが異なる。
- ECMAScriptに加えてWebAPIが使える。
- ECMAScript: プログラミング言語仕様。JavaScriptはECMAScriptに準拠している。ECMA-262とも表記される。
- Web API:JavaScriptコードからブラウザを操作するためのAPI。
- DOMの操作やWindowオブジェクト、localStorage, sesisonStorageへのアクセスなど。
- ブラウザ操作の用途なので、後述のサーバサイド用環境では使えない。
※以下の解説の図解が詳しかった。
ブラウザで動作するJavaScript
サーバサイド用環境
Node.jsが有名。DENO,BUNなどもある。
- Node.js: JavaScriptエンジンはV8を搭載。
- Node.jsは実行環境の名前。React.jsライブラリやVue.jsフレームワークといった、「JavaScriptのコードの集まり」とは明確に役割が異なる。
- Node.jsのフレームワークでは「Express」が有名。
- ECMAScriptの他にCommonJSも使える。
- Date,Mathなどの組み込みオブジェクトは、ECMAScriptの言語仕様に含まれているため、Node.js環境でも使える。
- CoomonJSではファイル操作用の
fs
モジュールの他、crypto
,process
,os
,stream
など多くの組み込みモジュールがある。
以下の記事が図解で大変詳しかった。
Node.jsで動作するJavaScript
前提2: Next.jsの概念
component
Client Component, Server Componentに大別される。
- Client Component: 従来のブラウザ環境。WebAPIの使用、useStateなどの状態管理が行える。
- Server Component: サーバサイドでHTMLをレンダリングしてブラウザに渡す。処理が高速で、機密情報を含む操作も行える。
↓使い分けの詳細は以下参照。
Server Component⇔API
Server/Client Componentでレンダリングの順が異なるので、API呼び出しを例にとって記載。
Server Component経由でAPIを呼び出した場合の処理。
API実行後、取得したデータも含めてから、HTMLを生成している。
Client Component⇔API
Client Component経由でAPIを呼び出した場合の処理。
一度ブラウザで画面をレンダリングした後で、APIを実行して、データを取得・反映している。
middleware
すべてのルートに対して必ず実行される。リクエスト実行前に必ず中継する。
本題: Next.jsの実行環境
runtime
それぞれの実行環境は以下。
- Client Side: ブラウザ環境を使用。
- Server ComponentからClient Componentをimportして呼び出すことはできる。importしたClient Componentの実行はブラウザ側で行われる。
- Client Component内で、Server Componentをimportはできない。(Hydration Errorになる)
- Server Side: Node.js環境を使用。
- Server Component, Server Actions, Route Handler (API)
- Server Actionsは別ファイルに定義することで、Server Component, Client Componentどちらからでも呼び出せる。(厳密には内部処理が異なるらしいが、結果的にどちらでも参照できる。)
- middleware: Edge Runtimeを使用。
- Edge Runtime →Node.jsベースだが、軽量な代わりに一部機能を制限したruntime。
-
request
,response
,fetch
などが使える。 -
fs
,process
,os
などは使えない。crypto
は一部のWebCrypto APIが使えるが、Node.jsのcrypto
モジュールは非対応。 - 軽量化を実現するために、重い処理の使用を意図的に制限している。
- v15.2以降は設定を追加することで、Node.js runtimeが実験的に使えるようになったらしい。
↓middlewareの実行環境、Node.js runtimeが使えるかについては以下の記事が詳しかった。
↓middlewareで動作するAPIは以下参照。
build
- 開発環境: localサーバで
next dev
で起動する。- リアルタイムでコード解析してコンパイルする。ライブ感。
- ビルド不要で動作するが、コードの増加につれて、サーバの動作が重くなる。
- 検証/本番環境:
next build
でビルドし、デプロイする。- ビルド時に、Client/Server/middlewareの実行環境別に振り分ける。
- ビルド時に分離・最適化を行うことで、動作が高速になる。
↓以下の「Local dev vs. production」項目にて言及されていた。
ローカル開発環境と本番環境 next devの開発プロセスは、next buildやnext startとは異なります。next devは、アプリケーション内のルートを開いたり移動したりするたびにコンパイルします。 これにより、アプリケーション内のすべてのルートがコンパイルされるのを待つことなく開発サーバーを起動できます。 productionビルドを実行すると、ファイルの最小化やコンテンツハッシュの作成など、ローカル開発では不要な他の最適化が適用されます。
まとめ
- ブラウザはGUIの他にエンジン各種やストレージ、NWなどから構成されている。
- JavaScriptの実行環境として、ブラウザ側とサーバ側に大別される。
- ブラウザ側は ECMAScript+WebAPI, Node.js側はECMAScript+CommonJSが使われている。
- WebAPIはブラウザのWindow、DOM、Storage等を操作できるAPI。Serverでは使えない。
- Next.jsでは Clientがブラウザ、ServerがNode.js、middlewareがEdge Runtimeが使われている。
- Edge Runtimeでは軽量な動作の代わりに、Node.jsでのファイル操作・プロセス制御など重い処理のmoduleが使えない。
- ローカルの開発環境ではリアルタイムでコード解析・実行環境別に振り分けられている。
- 検証・本番環境にデプロイする場合はビルド時に分離・最適化が行われ、高速な動作になる。またServer SideのコードがClient(ブラウザ側)に露出しないことが保証される。
最後に
JavaScriptの本質を理解するためには、ECMA Script言語仕様、runtime、ブラウザ構成など構造や背景の理解は必須だと思った。
Next.jsはruntimeを使い分けているから、ClientとServer側の処理を実装できるのだとわかった。
Next.jsはcacheが重要だとよく言われる。runtimeが「どこでコードが実行されるか」、cacheが「どこで結果を保存・再利用するか」なので、どのruntimeで実行されるかによって、cacheの戦略が変わる。
両者は連携してアプリのパフォーマンスを最適化しているため、cacheについても挙動を理解して、記事にまとめたい。
参考情報
Document
Next.js v15.3.4
のドキュメントを参照している。
- Next.js Doc: Edge Runtime
- Next.js Doc: How to optimize your local development environment
- Next.js Doc: middleware
- Next.js 日本語翻訳Doc: ServerとClientの構成パターン
- Next.js 日本語翻訳Doc: レンダリング
- MDN Web Docs 用語集: JavaScript engine (JavaScript エンジン)
- ECMA-262
Blog
- web.dev: ブラウザの仕組み
- Gaji-Labo++ blog: Next.js middleware の実行環境 Edge Runtime とは?
- Adk Nugey: JavaScriptランタイム(実行環境)について(図解)
- 発注ラウンジ: デプロイとはどういう意味?ビルドやリリースの違いとは
- AWS・Gooogle Cloudコラム: デプロイとは?コンパイル、ビルド、デプロイの違いを解説
Book
- 独習JavaScript (1章、17章)
- 実践Next.js (2章)
Discussion