Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Webレンダリング最適化の道

Avatar for Jeongmin LEE Jeongmin LEE
March 25, 2025
13

 Webレンダリング最適化の道

Avatar for Jeongmin LEE

Jeongmin LEE

March 25, 2025
Tweet

Transcript

  1. CONTENTS 1. Next.js SSR の限界 2. Code Splitting 3. React

    Server Component 4. Streaming & Selective Hydration 5. まとめ
  2. Suspense & React.lazy(2018年) React.lazy() によるクライアントサイドの Code Splitting ができるようになり、 Suspense により読み込み中の

    UI を制御できるようになった。 アプリケーションのコードを1つのファイルにまとめるのではなく、 複数のファイルに分割すること 例)ファストビューで見えるところだけ先に読み込んで、ほかは後で読み込む JS JS JS JS ↑Code Splitting あり ↑Code Splitting なし
  3. Suspense & React.lazy(2018年) React.lazy() によるクライアントサイドの Code Splitting ができるようになり、 Suspense により読み込み中の

    UI を制御できるようになった。 JavaScript を複数のファイルに分割する = UIのロード速度がそれぞれ違う
  4. Suspense & React.lazy(2018年) React.lazy() によるクライアントサイドの Code Splitting ができるようになり、 Suspense により読み込み中の

    UI を制御できるようになった。 ロード未完了のUIが完了するまで、 ローディングUIを出すことができる ↑ローディングUIあり ↑ローディングUIあり
  5. ① React と JSバンドルを送る ② JS ダウンロード、実行 ③ React 起動

    ④ useEffect 実行 ⑤ fetchProducts() を実行 ⑥ state にセット → 再レンダリング ⑦ HTML 描画 まず従来の React でデータフェッチしてみよう
  6. Server Component の動き ① fetchProducts() を実行 ② 取得したデータをもとに描画情報生成 ③ React

    と描画情報を送る ② React 起動 ③ React が DOM を構築 ④ HTML 描画
  7. Server Component の動き ① fetchProducts() を実行 ② 取得したデータをもとに描画情報生成 ③ React

    と描画情報を送る ② React 起動 ③ React が DOM を構築 ④ HTML 描画 Server Component が実行される クライアントに来てからは 変わることない コンポーネントそのものが クライアントに行くことはない
  8. +) Server-Side Rendering vs Server Component ➔ Server-Side Rendering ➔

    Server Component • 目的 → HTML を事前に生成して SEO や初期表示を改善 • できること → 事前にHTMLを生成してクライアントに送る • できないこと → JavaScript バンドルサイズを減らす • 目的 → クライアントに送る JS を最小化してパフォーマンスを改善 • できること → JavaScript バンドルサイズを減らす • できないこと → 事前にHTMLを生成してクライアントに送る RSCの出力結果は描画するに必要な情報であってHTMLそのものではない! 実際HTMLを生成するのはクライアント側のReact(JavaScript)
  9. +) Server-Side Rendering vs Server Component ➔ Server-Side Rendering ➔

    Server Component • 目的 → HTML を事前に生成して SEO や初期表示を改善 • できること → 事前にHTMLを生成してクライアントに送る • できないこと → JavaScript バンドルサイズを減らす • 目的 → クライアントに送る JS を最小化してパフォーマンスを改善 • できること → JavaScript バンドルサイズを減らす • できないこと → 事前にHTMLを生成してクライアントに送る RSCの出力結果は描画するに必要な情報であってHTMLそのものではない! 実際HTMLを生成するのはクライアント側のReact(JavaScript) つまり Server-side Rendering と Server Component 一緒に使ったら 事前にHTML生成もできるしJavaScript バンドルサイズも減らせていい感じ
  10. Next.js 13.4 からの大きな変化 2023年5月、App Router が Stableとして正式リリース! App Router からは

    React Server Components がデフォルトになる = データフェッチ方法に大きな変化が現れる
  11. Page Router の場合 Data Fetch 1 Data Fetch 2 Data

    Fetch 3 Data Fetch 4 getServerSideProps Client Component Client Component Client Component Client Component Client Component Client Component Client Component
  12. App Router の場合 Data Fetch 1 Data Fetch 2 server

    component Server Component Data Fetch 4 Data Fetch 3 Server Component Server Component Client Component Client Component Server Component Client Component コンポーネントごとのデータフェッチが可能になる
  13. Suspense & React.lazy を思い出してみよう JS JS JS React.lazy Suspense 2018年の

    Suspense は lazy だけ対応していたが、ゴールはサーバー側も対応すること! そしてそれが現実になり、SSRの限界を解決しにかかる Suspense が強くなる
  14. Streaming 従来のSSR Streaming これだけみると lazy + Suspense と同じように見えるかもしれないが、 大事なことは Streaming

    は Server Component と一緒に使われることだ! HTMLを完成を待たずに部分的にクライアントへ送信できる仕組み
  15. Suspense & React.lazy Data Fetch 1 Data Fetch 2 Data

    Fetch 3 Data Fetch 4 getServerSideProps Client Component Client Component Client Component Client Component Client Component Client Component Client Component できること = ここらへんののJSバンドルは 分割して後で読み込もう! できないこと = このデータフェッチを分割して 後で実行しよう!
  16. Streaming Data Fetch 1 Data Fetch 2 server component Server

    Component Data Fetch 4 Data Fetch 3 Server Component Server Component Client Component Client Component Server Component Client Component できること = データフェッチもHTML生成も非同期でする!
  17. Streaming Data Fetch 1 Data Fetch 2 server component Server

    Component Data Fetch 4 Data Fetch 3 Server Component Server Component Client Component Client Component Server Component Client Component できること = データフェッチもHTML生成も非同期でする! 非同期データフェッチ・HTML生成 (他のコンポーネントがこれを待たない) 非同期データフェッチ ・HTML生成 (他のコンポーネントが これを待たない)
  18. • SSRの限界 ◦ データフェッチがすべて終わってからHTML作成ができる ◦ すべてのJavaScriptがロードされてから Hydration できる • Code

    Splitting ◦ React.lazy + Suspense → クライアントのコードを分割できる ◦ next/dynamic → SSRの制御 + コード分割ができる • React Server Component ◦ サーバー上で実行され、その出力結果だけをクライアントに送る ◦ JSバンドルサイズを減らしパフォーマンス改善ができる • Streaming & Selective Hydration ◦ データフェッチ、HTML生成、Hydration を非同期でできる
  19. - nextjs.org, 「Loading UI and Streaming」, https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming - github.com, 「New

    Suspense SSR Architecture in React 18」, https://github.com/reactwg/react-18/discussions/37 - joshwcomeau, 「Making Sense of React Server Components」, https://www.joshwcomeau.com/react/server-components/ - plasmic, 「How React server components work: an in-depth guide」, https://www.plasmic.app/blog/how-react-server-components-work 参考資料