CSR, SSR とかの整理
用語整理。
レンダーという言葉について
CSR、SSR などの単語における「レンダー」(render) という単語は「React/Vue の要素を HTML 要素に変換する」程度の意味合いで使われている。ブラウザが HTML/CSS から Web ページを画面に表示することもレンダーと呼ばれるが、異なる。
本質はどこ?
ものによるが、本質がdata fetchingである可能性もありそう。Next.jsのドキュメントではSSR/SSGの使い分けのようなものではなくdata fetchingと題されているので。
CSR
client side rendering。ブラウザ上で ReactDOM.render()
を実行してReact要素をHTML [1] に反映させる。
初回ロードされるHTMLにはコンテンツが含まれていないので非常に薄く、<div id="react-root"></div>
のようなマウントターゲットとなる要素が置かれているぐらい。
- HTMLを読み込んでからJSを取得して実行することでコンテンツが読み込まれるため初回ロードに影響がある
- HTML/CSS/JSだけで完結するのでデプロイ先にはGitHub Pagesなども選択できる
- JSを実行しないとコンテンツが取れないので検索エンジン最適化に弱いという説があるが、最近のクローラはJSを解釈できるという説もある
- アカウントによって表示が異なるなどの場合分けがあり、Webアプリケーション向き
-
なんて呼べばいいのかわからない。DOMツリー? ↩︎
SPA
single page application。react-routerやvue-routerを使ってブラウザ上でのページ遷移を疑似的に再現しているアプリケーション。リンクをクリックしたときにはページの一部または全部を差し替えブラウザのURLを変更しHistory APIを使って履歴を追加する。
single pageというのは、ブラウザはページ遷移しているようにみえて実際には1ページで完結してるからだと思う。CSRとほぼ同義な気がするのはCSRがWebアプリケーション向けの特性を持っているから。SPAの技術はSSRやSSGの際にも使われることがある。
SSR
server-side rendering。リクエストが来たときにサーバー上で ReactDOM.renderToString
を実行してReact要素をHTML文字列に起こして返し、クライアント上で ReactDOM.hydrate
を実行して React の管理下にする。
初回ロードされるHTMLにはコンテンツが含まれる。
- コードを実行できるサーバーが必要になる
- サーバーはNext.js/Nuxt.jsの場合Node.jsだが、ReactDOMが動けばいいのでCloudflare Workersなどでもできる。Remixのことを言っている。
- Next.jsでは
getServerSideProps
を使うとリクエストが来た時に実行できる - SSGと比較して、リクエスト時にコンテンツを生成するので
- 理論上遅くなる
- 外部APIへのリクエストなどを毎回行えるので
- コンテンツが頻繁に変更される場合即座に反映できる
- APIを頻繁に呼ぶので時間的・金銭的コストがかさむ
GoやPHPやRubyで立てたサーバ上でHTMLテンプレートを使ってHTMLを動的に返すのに似ているが、ReactDOM.hydrate
される点が異なる。
GatsbyなどのSSGするツールにおいて ReactDOM.renderToString
することを「SSR」と呼んでいることがある (gatsby-ssr.js
など)。
SSG
static site generator。Reactよりも前からある言葉っぽい。原義はGoやPHPなどでHTMLテンプレートを使ってprogrammaticalにWebサイトを生成するもの。HugoとかJekyllとか。
SSRなどと対比される場合のSSGとは、適当なマシン上で ReactDOM.renderToString
を実行してReact要素をHTML文字列に起こしたものをデプロイし、リクエストがあったときはそれを単純に送信し、ブラウザ上で ReactDOM.hydrate
するもの。Gatsbyはもともとこの意味でのSSGに特化したフレームワーク。
SSRとSSGでやっていることは同じで、タイミングが異なるだけ。
- SSRと比較して、デプロイ前にコンテンツを生成するので
- リクエストに対する応答が早い
- WebサーバーはHTML/CSS/JSを返すもので十分
- GitHub Pagesなどにも載せられる
- コンテンツ変更のたびにビルドしなおしが必要なので、頻度が低いと良い
- Next.jsでは
getStaticProps
を使うとnext build
時に実行される- Next.jsではサイトではなくページ単位で使い分けるのでstatic generationと呼ぶことがある
- デプロイ前にすべてのページをレンダーするのでページが増えるほどデプロイに時間がかかる
ここからまったく自信ないゾーン。
ISR
incremental static regeneration。Next.jsの機能。中核コンセプトとしては「getStaticPropsでのSSGをリクエスト時に行える」というところか。
まず、eコマースサイトの各商品のうち人気の1000件だけを静的生成して残りの9000件はリクエスト時 (on-demand) に生成することでデプロイ時間を短縮、という使い分けテクニックが可能。
さらに、revalidate
に秒数指定ができる。この秒数は「生成したページがどのくらいの間有効か」を示している。ページ生成後n秒以内に来たリクエストに対しては生成済みのファイルを渡し、n秒以降に来たリクエストに対しては生成済みのファイルを渡しつつ裏側で再生成を行いキャッシュを更新する。キャッシュ更新後のリクエストにはその新しいページが返され、n秒経過後のリクエストに対してはまた再生成が走り…という流れ。
- SSGと比較して、単一ページごとに再生成が行えるため情報が頻繁に更新されるコンテンツでもビルド時間がかからない
- SSRと比較して、指定秒数内のリクエストではいちいち生成を行わないのでコストがかからない
- 一方で、指定秒数内のリクエストではページが使いまわされてしまうのでデータの更新に即座に反応できない
- さらに、Vercelでないと使えない
- 秒数指定のあたりっぽそう
実際に運用してみないとわからないところがあるが、検証するのがめんどくさそう。
DSG
deferred static generation。ページによってビルド時に生成するか初回リクエスト時に生成するかを選べる仕組み。ページによってSSGとSSRを使い分けてSSRをキャッシュするという戦略なのでは?
- Node.jsサーバーが必要
- Gatsby Cloudをおすすめされるがそれ以外でも可能らしい
DPR
distributed persistent rendering。