よくわからないことは生成AIに聞いてみよう!
Q. Next.jsを調べていて、プリレンダリングとかハイドレーションといった単語があってよくわからないので、このあたり解説してもらえますか?
↓
はじめに
本記事は会社勉強会での発表のための資料となります。
あと最近は業務でもNext.jsに携わることが増えてきたので、ちゃんと理解して使えるようになっておかねばという焦りなんかもあったりなかったり。
トピックとしてはキャッシュ周り、Server Actionsか、レンダリング方式かあたりのどれかをまとめようと思いましたが、レンダリング以外は難しそうだしまとめきれなさそうだったのでレンダリングの理解不足により、ビルドしたあとに予期せぬエラーが発生したりしたので、CSRやSSRといったレンダリングについて改めてまとめてみます。
対象のバージョン
Next.js 14.x
React 18.x
本記事の目標
大体以下のようなことが達成できれば◎
- そもそもいろいろなレンダリング手法がある背景、歴史について理解できる
- 各レンダリング方式について大枠が理解できる
- RSC(React Server Component)を抑えることができる
- RSCを知ることで、Next.jsがApp Router方式を採用する背景に何があったのかが理解できる
- Reactの文脈のクライアントコンポーネント、サーバーコンポーネントの違い
ReactとNext.jsの歴史
- (図にはないが)React登場以前、いわゆるシンプルなMPA時代
- 2013年 Reactがリリース(CSR:クライアントサイドレンダリング)
- 2016年 Next.jsがリリース(SSR:サーバーサイドレンダリング)
- 2020年 React Server Component(RSC)の登場
- 2023年 Next.js13.4でApp Routerが安定版リリース
このあたりの歴史の流れについては、以下の記事で詳細に記載されています。
Next.jsから学ぶWebレンダリング ~React誕生以前からApp Router with RSCまでの流れ~
2013年
まずReactが登場したことによってCSRという概念が一般的なものとなりました。
それ以前からBackbone.jsやAngularなどによるSPAアプリケーション自体はすでに存在していましたが、やはり普及に最も影響力があったのはこのタイミングな気がします。
2016年
その後、CSRの課題である初期表示の遅さやSEO課題などが指摘されるようになり、それらを解決するために登場してきたのが、Next.jsやNuxt.jsといったSSRが可能なフレームワークです。
2020年
React Server Componentと呼ばれる新たな仕組みが登場しました。
RSCについては後述。
2023年
Next.js側でRSCを利用できるようなアーキテクチャに寄せるべく、AppRouterと呼ばれるルーティングシステムが登場しました。
大きな変更点が多々ありますが、今回の記事としてはやはり、デフォルトのレンダリングがCSRからSSRに変更になったという点でしょうか。
CSR、SSR、SSG
CSR クライアントサイドレンダリング
後述するSSRやSSG含め、個人的には一番シンプルなレンダリング手法かと思います。
クライアントからの要求を受取、最低限のHTML
<div id="root"></div>
のようなDOMとJavaScriptを返します。
SSR サーバーサイドレンダリング
初期表示が大きく変わり、今度はサーバー側で「完全なHTML + JavaScript」を生成して、それをブラウザに返却するようになりました。
さて、SSRの文脈を追うことで、記事の最初に出てきていた「ハイドレーション」というキーワードが出てきました。
ハイドレーションとは何なのでしょうか。
ハイドレーションとプリレンダリング
ハイドレーションとは日本語でいうと「水分補給」という意味です。
webフロントエンドの文脈から見ると
「まだ動きがついていない、乾いた状態のHTMLにJavaScript(水分)を注入することで動きのある状態に変化させること」
といった意味での解釈が妥当になりそうです。
ハイドレーションを行うことで、ボタンをクリックした際のイベントが登録され、インタラクティブなWebの画面を表示することができるようになります。
movableJavaScriptみたいなわかりやすい単語じゃだめだったのかしら
プリレンダリングとは、このサーバー側で事前にHTMLを生成しておくことです。
「Pre」とは「あらかじめ」という意味ですから、こちらはハイドレーションと比較するとそもままの意味で受け取れますね。
Next.jsにはプリレンダリングを行うには、このSSRと後述するSSGのどちらかを選択することになります。
ここまでくると冒頭のハイドレーションとプリレンダリングについての解説も混乱することなく読めそうです。
SSG スタティックサイトジェネレーション
今までの2つがリクエスト時にどこかでページを生成していたのに対して、こちらは事前に生成しておいたページをリクエスト時に配信するような形式です。
動的なデータがたくさんあるようなサイトには向きませんが、更新の少ないサイトであれば一度ページを生成してしまえばよいので、そういった条件に合致する場合は非常にパフォーマンスの良い選択肢となるでしょう。
RSCとは何ぞや?
RSCが登場したことによって、その技術を利用すべくNext.jsがAppRouterをいうルーティングシステムを導入したという話をしましたが、そもそもRSCとは何でしょうか。
サーバコンポーネントは新しいタイプのコンポーネントです。クライアントアプリケーションや SSR サーバとは別の環境で、バンドル前に事前にレンダーされます。
React Server Components の “server” とはこの別の環境を指しています。サーバコンポーネントは、CI サーバでビルド時に一度だけ実行することも、ウェブサーバを使用してリクエストごとに実行することもできます。
RSCによって何ができるようになったかというと、「クライアントコンポーネント」「サーバーコンポーネント」というコンポーネント単位でレンダリングを分けることができるようになったという点です。
RSC登場以前は、クライアントコンポーネントしか存在しませんでした。
それまでもCSRとかSSRといった棲み分け自体はありましたが、あくまですべてクライアントコンポーネントであり、「サーバーのみで実行されるコンポーネント」というものはなかったようです。
(ここ勘違いしたせいで混乱しましたが、RSCによってサーバーコンポーネントというものが初めて登場したようです)
TODO
SCが登場したことで何が嬉しかったの?か書く
SCだとできないこと(useStateとかできないよねとか)
逆にSCがあると嬉しいこと(トークンとかの秘密情報はサーバーにしかなくて、クライアントにはわたってこないとか)
AppRouterにおけるSSR
前述したSSRの図は、RSC登場以前のPagesRouter時代のものでしたが、AppRouterにおいては、ページ単位よりも、更に細かなコンポーネント単位でレンダリングを実行することが可能になりました。
しれっとRSC Payloadとか言う単語が出てますが、これはSCでのレンダリング結果や、SCからCCに渡すpropsのデータなどをまとめたjsonのようなフォーマットでのメタデータのようなものです。
PPR(パーシャルプリレンダリング)
力尽きたので割愛します
すごく簡単に言うとRSC登場によってCCとSCの併用が可能になりましたが、さらにSSRとSSGの併用も可能になるようです。またまた、なんだかよくわかりませんね
参考資料
一言で理解するReact Server Components
Next.jsから学ぶWebレンダリング ~React誕生以前からApp Router with RSCまでの流れ~
React Server ComponentsとApp Routerをそろそろちゃんと理解したい
How React 18 Improves Application Performance
Next.js 公式Rendering
React Server Componentsの仕組み:詳細ガイド
Next.js App Router / React Server Components(RSC)を紐解いてみた