Share
Embed
App Router への移行は「改善」となり得るのか?/ Can migration to App Router be an improvement
フロントアーキテクチャ改善NIGHT https://hireroo.connpass.com/event/310150/
Takepepe
March 26, 2024
Transcript
56 slides
-
実践Next.js – App Router で進化する Web アプリ開発 ▪ 2024.3/16 技術評論社より刊行 ▪ Next.js
App Router を題材にした書籍 ▪ 一通りの機能を備えたサンプル App を対象に解説 ▪ 公式ドキュメントの分かりづらい箇所を重点的に -
これらの機能は Next.js 固有のものではなく、 React 共通のもの ▪ React の新しい機能が使用できる ・ RSC(React Server Components)がデフォルトで使用される
・ Server Component / Client Component の境界がある ・ Server Action が使用できる 従来 Pages Router との差分 【1】App Router 登場の背景 -
パフォーマンス向上のための機能 ▪ React の新しい機能が使用できる ・ RSC(React Server Components)がデフォルトで使用される ・ Server Component / Client
Component の境界がある ・ Server Action が使用できる 従来 Pages Router との差分 【1】App Router 登場の背景 -
ページ単位で CSR を行うも、全ての実装が共通チャンクに含まれる (※ React.lazy による Dynamic import で分割し、最適化する方法もあります) 従来
SPA のパフォーマンス課題 【2】パフォーマンスへの影響 Request Response Web Server per page chunk per page chunk per page fetch HTML Commons chunk fetch Page render (CSR) -
いずれかのページ実装増加が、全ページのパフォーマンスに影響する (※ React.lazy による Dynamic import で分割し、最適化する方法もあります) 従来 SPA のパフォーマンス課題
【2】パフォーマンスへの影響 Request Response Web Server per page chunk per page chunk per page fetch HTML Commons chunk fetch Page render (CSR) -
ページ単位で チャンクが分割されている Pages Router のページ毎のチャンク 【2】パフォーマンスへの影響 fetch render (CSR) Request
Response Next.js HTML DOM Request Response Next.js HTML DOM Request Response Next.js HTML DOM page chunk page chunk page chunk -
いずれかのページチャンク増加は、該当ページに「のみ」パフォーマンス影響がある Pages Router のページ毎のチャンク 【2】パフォーマンスへの影響 fetch render (CSR) Request Response
Next.js HTML DOM Request Response Next.js HTML DOM Request Response Next.js HTML DOM page chunk page chunk page chunk -
▪ 利点 ・ ページ固有の実装は、ページ単位のチャンクに分割される ・ ページ固有の実装は、他ページに影響を与えない ・ チャンクの共通化は、自動で行われる ・ ページ毎に、レンダリング手法(SSG / ISR / SSR)を選べる Pages
Router のメリット ページが増えても、他ページのパフォーマンスが劣化しにくい構造 【2】パフォーマンスへの影響 -
ただし、1ページ内のコンテンツ増加に対して、チャンク増加は不可避だった Pages Router のページ毎のチャンク 【2】パフォーマンスへの影響 fetch render (CSR) Request Response
Next.js HTML DOM Request Response Next.js HTML DOM Request Response Next.js HTML DOM page chunk page chunk page chunk -
ただし、1ページ内のコンテンツ増加に対して、チャンク増加は不可避だった Pages Router のページ毎のチャンク 【2】パフォーマンスへの影響 fetch render (CSR) Request Response
Next.js HTML DOM Request Response Next.js HTML DOM Request Response Next.js HTML DOM page chunk page chunk page chunk -
App Router(RSC) は、このチャンク増加をなるべく避ける仕組みを提供します Pages Router のページ毎のチャンク 【2】パフォーマンスへの影響 fetch render (CSR)
Request Response Next.js HTML DOM Request Response Next.js HTML DOM Request Response Next.js HTML DOM page chunk page chunk page chunk -
リクエスト時、ページのデータを取得 Pages Router の SSR fetch Request Server { "tags":
[...], "articles": [...], "recommendations": [...], "categories": [...], } getPageData JSON 【2】パフォーマンスへの影響 -
レスポンス後、ページに必要なチャンクを読み込み、ページ全体を hydration Pages Router の SSR fetch render hydration Response
Request Browser Server TTFB 【2】パフォーマンスへの影響 -
レスポンス後、ページに必要なチャンクを読み込み、ページ全体を hydration Pages Router の SSR fetch render hydration Response
Request Browser Server 【2】パフォーマンスへの影響 JS TTFB -
ページ全体がインタラクティブに Pages Router の SSR fetch FID render hydration Response
Request Browser Server 【2】パフォーマンスへの影響 JS TTFB -
▪ 欠点 ・ ページに必要なデータが多くなるほど、 TTFBが遅くなる ・ ページのコンテンツが多くなるほど、ページのチャンクが肥大化する ・ ページのコンテンツが多くなるほど、 hydration に時間がかかる ・ ページのチャンク肥大化に伴い、 FID が遅延
Pages Router の SSR ページの肥大化にともない、パフォーマンスが劣化する構造 【2】パフォーマンスへの影響 -
▪ 欠点 ・ ページに必要なデータが多くなるほど、 TTFBが遅くなる ・ ページのコンテンツが多くなるほど、ページのチャンクが肥大化する ・ ページのコンテンツが多くなるほど、 hydration に時間がかかる ・ ページのチャンク肥大化に伴い、 FID が遅延
Pages Router の SSR Next.js に限らず RSC ではない SSR の場合、共通の課題 【2】パフォーマンスへの影響 -
ビルド時に予め「静的データ」を取得 App Router の Streaming SSR build Server { "tags":
[...], "articles": [...], "categories": [...], } getStaticData JSON 【2】パフォーマンスへの影響 -
リクエスト時に「動的データ」を取得 App Router の Streaming SSR fetch Request Server 【2】パフォーマンスへの影響
{ "recommendations": [...], } getDynamicData JSON -
動的データ取得中でも、 Streaming でレスポンスが返せる App Router の Streaming SSR fetch Response
Request Server Browser 【2】パフォーマンスへの影響 TTFB { "recommendations": [...], } getDynamicData JSON -
送られたコンポーネントから個別に hydration が行われる(コンポーネント単位のチャンク) App Router の Streaming SSR fetch hydration
Response Request Browser Server 【2】パフォーマンスへの影響 TTFB -
送られたコンポーネントから個別に hydration が行われる(コンポーネント単位のチャンク) App Router の Streaming SSR fetch hydration
Response Request Browser Server 【2】パフォーマンスへの影響 JS JS TTFB -
「動的データ」の取得が完了し、部分的なレンダリング結果が返される App Router の Streaming SSR fetch hydration Response Request
Browser Server 【2】パフォーマンスへの影響 JS JS TTFB -
後から送られてきたコンポーネントの hydration も始まる App Router の Streaming SSR fetch hydration
Response Request Browser Server 【2】パフォーマンスへの影響 JS JS JS TTFB FID -
ページ全体がインタラクティブに App Router の Streaming SSR fetch hydration Response Request
Browser Server 【2】パフォーマンスへの影響 JS JS JS FID TTFB -
▪ 利点 ・ ページに必要なデータが多くなっても、 TTFBが遅くならない ・ ページのコンテンツが多くなっても、ページのチャンクが肥大化しにくい ・ ページのコンテンツが多くなっても、 hydration は適宜行われる ・ ブラウザに必要な JS が最小限であり、チャンクはコンポーネント毎に分割
App Router の Streaming SSR ページが肥大化しても、パフォーマンスが劣化しにくい構造 【2】パフォーマンスへの影響 -
▪ 利点 ・ ページに必要なデータが多くなっても、 TTFBが遅くならない ・ ページのコンテンツが多くなっても、ページのチャンクが肥大化しにくい ・ ページのコンテンツが多くなっても、 hydration は適宜行われる ・ ブラウザに必要な JS が最小限であり、チャンクはコンポーネント毎に分割
App Router の Streaming SSR さらにナビゲーション時、必要なコンポーネントのみ SSR されるため、データ取得効率が良好 【2】パフォーマンスへの影響 -
▪ RSC はパフォーマンス改善となりうるのか? ・ RSC では、チャンクがコンポーネント単位で細分化される ・ RSC に最適化された App Router キャッシュは、パフォーマンス向上に寄与 ・ 中長期的にみて「劣化しにくい」構造が得られる
パフォーマンスへの影響まとめ 画面構成要素が少ない場合、差が生まれにくいのも事実 【2】パフォーマンスへの影響 -
▪ 【構成例1】SPA + BFFサーバーパターン(非 Next.js) ▪ 【構成例2】Next.js の Routing のみ活用パターン ▪ 【構成例3】Next.js の
BFF フル活用パターン 筆者が直面したことのある構成 アーキテクチャ上の Next.js 立ち位置 【3】アーキテクチャへの影響 -
アーキテクチャ上の Next.js 立ち位置 【3】アーキテクチャへの影響 BFF Server Web API Request Web
Server Data Source 【構成例1】SPA + BFFサーバーパターン(非 Next.js) DB SPA -
アーキテクチャ上の Next.js 立ち位置 【3】アーキテクチャへの影響 BFF Web API Request SSG +
SPA Data Source 【構成例2】Next.js の Routing のみ活用パターン DB Server Next.js -
アーキテクチャ上の Next.js 立ち位置 【3】アーキテクチャへの影響 Web API Request SSG / ISR
SSR + SPA Data Source 【構成例3】Next.js の BFF フル活用パターン DB Server Next.js -
▪ 【構成例1】SPA + BFFサーバーパターン(非 Next.js) ・ Node.js サーバーを運用したくない現場(監視面、チューニング面など) ・ Vite(create-react-app)や、最近だと Remix SPA モード
を採用 ・ Next.js Pages Router の Static Export で乗り切るパターンも存在 ・ FE/BE をキッチリ分割したい現場向け 運用面 >>> パフォーマンス アーキテクチャ上の Next.js 立ち位置 【3】アーキテクチャへの影響 -
▪ 【構成例2】Next.js の Routing のみ活用パターン ・ Next.js の Static Export だと Dynamic
Route が処理しづらい ・ ファイルシステムベース Routing が便利なので使用している ・ Node.js 製の BFF サーバーは、BEエンジニアが実装 認証認可実装は、構成例 1と同じ アーキテクチャ上の Next.js 立ち位置 【3】アーキテクチャへの影響 -
▪ 【構成例3】Next.js の BFF フル活用パターン ・ 認証認可を Next.js の BFF で行う ・ 外部
WEB API サーバーは、BE エンジニアが開発 ・ 外部 WEB API サーバーは、マイクロサービス化されていることも ・ BFF から ORM(DBサーバー)を直接使うことも Node.js(Next.js)サーバーのチューニングや運用の知見が求められる アーキテクチャ上の Next.js 立ち位置 【3】アーキテクチャへの影響 -
▪ 【構成例1】SPA + BFFサーバーパターン(非 Next.js) ▪ 【構成例2】Next.js の Routing のみ活用パターン ▪ 【構成例3】Next.js の
BFF フル活用パターン App Router への移行は 「改善」となり得るのか? 【3】アーキテクチャへの影響 -
▪ 【構成例1】SPA + BFFサーバーパターン(非 Next.js)❌ ▪ 【構成例2】Next.js の Routing のみ活用パターン ▪ 【構成例3】Next.js の
BFF フル活用パターン Next.js サーバーを運用しない場合、メリットは今の所無い App Router への移行は 「改善」となり得るのか? 【3】アーキテクチャへの影響 -
▪ 【構成例1】SPA + BFFサーバーパターン(非 Next.js)❌ ▪ 【構成例2】Next.js の Routing のみ活用パターン ✅ ▪ 【構成例3】Next.js
の BFF フル活用パターン ✅ App Router への移行は 「改善」となり得るのか? 【3】アーキテクチャへの影響 Next.js サーバーを運用している場合、パフォーマンス面でメリット -
▪ App Router では React の新機能 Server Action が使える ・ Form を通じ、サーバーの更新処理がダイレクトに行える
・ 中継点として設けていた WEB API(API Routes、Route Handlers)が不要に 他 React 製フレームワークでも Server Action は今後採用例が出る見込み 【3】アーキテクチャへの影響 App Router への移行は 「改善」となり得るのか? -
▪ WEB API は RESTful API の方が都合が良い ・ キャッシュの再利用がしやすく、 revalidate が単純 ▪ 別立ての
BFF サーバーは恐らく不要に ・ Server Component / Server Action で ORM を使用する機会が増加 ▪ Page 層で req / res オブジェクトが使用不能に ・ req / res を使用している従来のコードは再検討が必要 App Router への移行は 「改善」となり得るのか? 【3】アーキテクチャへの影響 App Router を採用する場合、従来アーキテクチャへの影響は大きい -
▪ まとめ ・ App Router への移行は、フロント外のアーキテクチャにも影響を及ぼす ・ App Router への移行は、既存構成によって難易度が異なる ・ アーキテクチャ改善というより、改変になる App Router
への移行は 「改善」となり得るのか? 【3】アーキテクチャへの影響 各位、メリット/デメリットを比較して