個人開発でサクッとアプリ作るならnextで決まり!と個人的には結論が出てきているところですが、久しぶりに開発しようとしたらレンダリングの手法などについて色々忘れていたので備忘録としてまとめます。
1. 基本概念のまとめ
1. SSG(Static Site Generation:静的サイト生成)
概要
・ビルド時にHTMLを生成し、リクエスト時にはキャッシュ済みのHTMLを配信。
※ビルドのタイミングでまとめてデータを取得し、それを埋め込んだHTMLを生成。
・条件を満たしている限りは、デフォルトでこの方法でレンダリングされる。
※hookなどクライアントサイドで動く処理を含む場合静的生成できない。(nodeサーバ上でビルドされるが、クライアントサイドに依存した処理はサーバ上で実行できないため)
・レンダリングのタイミングが異なるが本質的にはSSRと同じ手法でレンダリングされる。
2.SSR(Server-Side Rendering:サーバーサイドレンダリング)
概要:
・リクエストごとにサーバーでHTMLを生成してクライアントに送信。
・SSGのレンダリングがユーザーのアクセスのたびにサーバーサイドで実行されるイメージ(都度サーバ側でフェッチした値を埋め込んでレンダリングできる)
・初期表示はSSGより遅くなるが、リアルタイム性が必要な場合に適している。
3. CSR(Client-Side Rendering:クライアントサイドレンダリング)
概要:
・クライアントがブラウザ上でJavaScriptを実行してHTMLを生成。(従来からのreactのレンダリング方法)
・サーバーサイドではHTMLを生成しない。(実態はほぼ全てjsコードで、それを実行することでHTMLが生成される)
・事前にHTMLが生成されないためSEOに弱い
・ステート等クライアントサイドに依存した機能を使う場合、CSRになる
まとめ
基本的には、SSG、SSR、CSRの順で優先順位を考えておけば問題ない。できるだけSSGで事前にレンダリングし、リアルタイムにDBから値を取得したいような場面ではSSR、ステートなどクライアントサイドに依存したreactの機能を使う場合のみCSRを使う。
一見するとCSRは避けるべきもの、あまり使われないもののように見えかねないが、いかにもSPA的な動きをするwebアプリを作る場合は大部分がCSRになる(多分)
next特有の概念
上記のレンダリング方法は従来ではページ単位で指定していたが、next13以降ではコンポーネント単位で指定可能となった。
サーバーコンポーネント(Server Components)
概要
・平たく言えば、SSG,SSRによって、サーバーサイドレンダリングされるコンポーネント
・デフォルトでは全てのコンポーネントがサーバーコンポーネントとして扱われる
1.5 クライアントコンポーネント(Client Components)
概要
・クライアントサイドで動作するReactコンポーネント。CSRでレンダリングされる。
・明示的に'use client'
を指定することでクライアントコンポーネントとなる。
・useEffect
, useState
などのフックを利用可能。
まとめ
レンダリングのパターンと合わせて考えると、可能な限り全てのコンポーネントをサーバーコンポーネントとして扱い、サーバーサイドでレンダリングするべきと考えられる。またその中でも、リアルタイム性の求められるデータがない場合にはSSGで事前に静的なファイルとして生成すべきである。
これを前提に、どうしてもreact hooksのようなクライアント側の処理やブラウザAPIの使用が必須な場合のみをクライアントコンポーネントとして抜き出し、クライアント側の処理を最小限に抑える、このような考え方が感じ取れる。
サーバーサイドとクライアントサイドの責務を明確に分離!
クライアントサイドでのJavaScript量を最小限にし、パフォーマンスを向上!
みたいなところが落とし所かな〜と考えています。他方で個人開発レベルの小規模アプリケーションの場合そこまで深く意識せずとも動作の際はあまり感じられないかとも思いますので、できるだけ静的生成しておいてCDNでホスティングすることを意識できればユーザー体験は悪くないしなおかつ楽に開発できるな〜といった所感です。