Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
App Router への移行は「改善」となり得るのか?/ Can migration to ...
Search
Takepepe
March 26, 2024
Programming
8
3.2k
App Router への移行は「改善」となり得るのか?/ Can migration to App Router be an improvement
フロントアーキテクチャ改善NIGHT
https://hireroo.connpass.com/event/310150/
Takepepe
March 26, 2024
Tweet
Share
More Decks by Takepepe
See All by Takepepe
ServerAction で Progressive Enhancement はどこまで頑張れるか? / progressive-enhancement-with-server-action
takefumiyoshii
7
890
フロントエンドの書くべきだったテスト、書かなくてよかったテスト
takefumiyoshii
39
15k
Webフロントエンドのための実践「テスト」手法 CodeZine Night #1
takefumiyoshii
24
8.5k
Next.js でリアーキテクトした話 / story-of-re-architect-with-nextjs
takefumiyoshii
12
8.7k
より速い WEB を目指す Next.js / nextjs-make-the-web-faster
takefumiyoshii
54
20k
フロントエンドの複雑さに耐えるため実践したこと / readyfor-nextjs-first
takefumiyoshii
25
11k
Redux の利点を振り返る
takefumiyoshii
26
8.7k
Type-only Migrate by AST
takefumiyoshii
1
640
- Regular expression & Type - Naming Rule Linter
takefumiyoshii
1
380
Other Decks in Programming
See All in Programming
事業成長を爆速で進めてきたプロダクトエンジニアたちの成功談・失敗談
nealle
3
1.3k
型のインスタンス化は非常に深く、無限である可能性があります。
kimitashoichi
0
140
Develop iOS apps with Neovim / vimconf_2024
uhooi
1
320
聞き手から登壇者へ: RubyKaigi2024 LTでの初挑戦が 教えてくれた、可能性の星
mikik0
1
150
たのしいparse.y
ydah
3
110
Reckoner における Datadog Browser Test の活用事例 / Datadog Browser Test at Reckoner
nomadblacky
0
190
Recoilを剥がしている話
kirik
0
1k
フロントエンドのディレクトリ構成どうしてる? Feature-Sliced Design 導入体験談
osakatechlab
7
3.7k
N.E.X.T LEVEL
pluu
2
270
flutterkaigi_2024.pdf
kyoheig3
0
470
DevTools extensions で 独自の DevTool を開発する | FlutterKaigi 2024
kokiyoshida
0
450
cmp.Or に感動した
otakakot
3
340
Featured
See All Featured
Testing 201, or: Great Expectations
jmmastey
40
7.1k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
480
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Into the Great Unknown - MozCon
thekraken
33
1.5k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
247
1.3M
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
0
31
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
890
Transcript
フロントアーキテクチャ改善 NIGHT App Router への移行は 「改善」となり得るのか?
自己紹介 ▪ Takepepe(吉井 健文) ▪ フロントエンドエンジニア ▪ 社内横断開発組織に所属 ▪ フロントエンド開発の横断サポート
実践Next.js – App Router で進化する Web アプリ開発 ▪ 2024.3/16 技術評論社より刊行 ▪ Next.js
App Router を題材にした書籍 ▪ 一通りの機能を備えたサンプル App を対象に解説 ▪ 公式ドキュメントの分かりづらい箇所を重点的に
▪ 【1】App Router 登場の背景 ▪ 【2】パフォーマンスへの影響 ▪ 【3】アーキテクチャへの影響 Agenda
【1】App Router 登場の背景
これらの機能は 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 登場の背景
▪ RSC に適したキャッシュ機構をもつ ・ RSCペイロードと呼ばれるレンダリング結果をキャッシュ ・ コンポーネント単位で、キャッシュの存続期間をコントロール ・ 動的/静的を区分し、キャッシュを作成 ・ キャッシュにより、更なるパフォーマンス向上が見込まれる App Router の優位性 【1】App
Router 登場の背景
【2】パフォーマンスへの影響
▪ SPA でも十分速いのですが… ・ ページ総数が増加するとどうですか? ・ 各ページのコンテンツが肥大化するとどうですか? パフォーマンス向上と言われても… 【2】パフォーマンスへの影響 将来も、現状と同じパフォーマンスを維持できるでしょうか?
ページ単位で 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 【2】パフォーマンスへの影響 ready Server
リクエスト時、ページのデータを取得 Pages Router の SSR fetch Request Server 【2】パフォーマンスへの影響
リクエスト時、ページのデータを取得 Pages Router の SSR fetch Request Server { "tags":
[...], "articles": [...], "recommendations": [...], "categories": [...], } getPageData JSON 【2】パフォーマンスへの影響
取得したデータを使用し、ページを render Pages Router の SSR fetch render Request Server
【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 Server build 【2】パフォーマンスへの影響
ビルド時に予め「静的データ」を取得 App Router の Streaming SSR build Server { "tags":
[...], "articles": [...], "categories": [...], } getStaticData JSON 【2】パフォーマンスへの影響
「静的データ」でレンダリングできる部分は、予めレンダリングしておく App Router の Streaming SSR ready Server 【2】パフォーマンスへの影響
リクエスト時に「動的データ」を取得 App Router の Streaming SSR fetch Server Request 【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】パフォーマンスへの影響
【3】アーキテクチャへの影響
▪ 【構成例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】アーキテクチャへの影響 各位、メリット/デメリットを比較して
ご清聴ありがとうございました