React Server Components(以下、RSC)はサーバ立てなくても使えるよ、という記事を読んで、最近やってたことに関連する領域(つまり、興味あることだけ)を把握した。
RSCの世界ではデフォルトがサーバコンポーネントで、HTMLのレンダリングが(で合ってる?)ブラウザ上ではない環境、つまり「サーバ」で起こる。ブラウザはやることが減ってパフォーマンスに効くし、さらにはレンダリングが依存するデータ取得もブラウザ外に出せる。部分的に外に出せる。外に出せない部分は全部クライアントコンポーネントで、今まで通りのReact。Reactの世界の内部にそういう境界がある。
この境界はコンポーネントの親子関係(レンダーツリー)ではなく、それを定義する(ES Module的な意味での)モジュールの依存関係のツリー上にあるのが混乱ポイントになりそう。クライアントコンポーネントが依存つまりimportしてるものは全てクライアントコンポーネントになる。だから、(依存されうる)コンポーネント側の定義を見ても、それがサーバコンポーネントかどうかは確定しない(場合がある)。このあたりの話が丁寧に書かれてるのが'use client'のページなのがちょっと不思議な感じ。
実行環境としてのブラウザが動的にやっている依存解決の位置に境界があるってことなんだろうけど、どっちなのかコンポーネント定義のファイル自身が定義していてエディタで色が変わる、ぐらいの分かりやすさがほしくなってしまう。React Server Components自体が微妙な表現かもしれず、RSCという新しい仕組みの中にサーバコンポーネントとクライアントコンポーネントがある、という区分けになってるっぽい。「'use client' は React Server Components 用の機能です」とか言われて混乱する。そもそも非ブラウザ環境を「サーバ」と呼ぶのも変だけど、それは主なターゲットとなるユースケースなんだろうね。
実態としてはこんな感じ?
- React Rendering Environment Separation
- Browser Components
- Inbound Components
いずれにせよ、最適化のための戦略は難しそう。勝手に良い感じにやっとくのを超えて、ユーザに協力してもらうためにはどうしたらいいか、という話ね。かっこついてたほうがいいかもしれない。
ある世界の内部に異なる環境がある、という意味での面白さだと、Next.jsもそういう面がある。データ取得の静的なもの(ビルド時)と動的なもの(リクエスト時)が1つのページ定義の1つのファイルの中に存在していて、かつ、そのデータを渡す先のReact(のコンポーネント)がいる。この混ざり方、繋がり方が面白くて興味を持ったのが昔々。
で、React Server Componentsにとっての「サーバ」というのはブラウザの外部のことなので、CIサーバ上でも良いし、ローカルマシン上でも良い、というのが「サーバ立てなくても使えるよ」という冒頭の話。「サーバ立てなくても使えるよ」というだけなら、Next.jsのstatic exportsもそうだし、このサイトの出力に使っているrenderToStaticMarkupも同じ。違うのは、Reactの世界の内部に境界を持てるかどうか。Reactが動くCSRなSPAの一部を事前にレンダリングしておけるのがサーバコンポーネント。一部と言わずほぼ全部にしてもいい。(もちろんリクエスト時に一部をサーバサイドでレンダリングできて、それが表向きのアピールポイントなはず。)
このサイトとしてはSPAをやりたいわけではないからReactが動く必要はなく、JSXを扱えるメジャーなレンダリングシステムとしてReactとその関連技術を使い続けているわけだけど、ありうる選択肢として違いが見えて楽しかった。まだちゃんと分かってないところの理解にも繋がりそう。