重いJSバンドルや、バックエンドのデータリソースへのアクセス性など、さまざまな課題を解決するためのソリューション。
簡潔に言えば、サーバ側で実行されるReactのコンポーネントです。
Server ComponentとClient Componentをシームレスに結合させ、クライアントとサーバ側をまたがってアプリ構築ができる・・・といった説明がされています。
公式の資料は以下です、
特徴
サーバー側で実行されるServer Componentと、クライアント側で処理されるClient Component(これまで作成していたコンポーネントと同様のもの)を組み合わせて構築します。
それぞれxxx.server.jsx
とxxx.client.jsx
といった命名ルールを採っています。
- サーバ側で実行されるコンポーネントは、当然サーバーサイドの資源にアクセスできる
- 新たにAPIエンドポイントを作ったりせず、直接DBアクセスなどができる
- 処理された結果のコンポーネントを直列化し、ストリーミングレスポンスする
- サーバ側コンポーネントと、その依存ライブラリはクライアント側スクリプトにはバンドルしないため、バンドルサイズが削減できる
といった特徴があります。
SSRとの違い
SSRはレンダリング後の「HTML」をレスポンスされます。
一方、Server ComponentsではClient componentの情報とDOMツリーのようなものがJSONっぽく返ってきます。
demo projectで試してみました。
このJSONっぽく直列化された情報をクライアント側でhydrate的なことをしているようですね。
サーバー側の処理では、ルートのサーバーコンポーネント以下の子要素を全てレンダリングしてレスポンスするようなことがRFCには書いてあります。
レスポンスされるのはコンポーネント情報であるため、Reactを利用してすでに画面で表示している内容とマージして、クライアント側のレンダリングを行うことができる。
このため、クライアント側で状態を維持しつつ、何度もServer Componentの再取得できる。
これがSSRとの違いのようです。
説明動画でもSSRとの違いについて触れています。また、SSRとの併用についても軽く言及していました。
ちなみにこのレスポンス内容、demo projectの初期表示時で3kb強、Noteを選択時で4kb程ありました。
前述したようにルートのサーバーコンポーネント以下の子要素を全てレンダリングしているため、それなりのサイズになっているようです。
複雑なUIで適当にやると普通にAPIを使うのに比べて、通信量がかなり増えそうてしまいそうです。
(画面の一部のみ再取得できるように検討している、との話はあります)
server componentとclient componentの制約
RFCに書かれています。
Server componentでは状態を持てない、useEffectなども使えない、Client component側ではServer componentをインポートできない・・・など、制約があるようです。
言われてみればそうでしょうね、といった感じの内容ではありますが。
サーバ側でもクライアント側でも使えるShared componentもあります。
当然、Server/Client component両方の制約が適用されます。
感想
webとJavaScriptは現状深い関係なので、JavaScriptだけで完結できるというメリットはありそうです。
ただ現状の情報だけだと手を出しづらい気がします。
結構複雑だし、状態管理やコンポーネント構成などもこれまでの開発とは大きく変わるような気がします。
もちろん、まだ開発段階なので今後もっと使いやすくなる可能性はありますが。
また、特に情報量の多い画面構成だと、前述したようにServer componentのレスポンスが大きくなってしまいそうなので、うまく設計してやる必要がありそうです。
その場合、キャッシュの管理も複雑になる可能性もあります。(demoではnotesの取得をキャッシュする処理が入っていました)
バックエンドの規模が小さく、動的コンテンツの表示を早くしたい・・・といった場合に適している感じでしょうか。
「シンプルなアプリなのでフロントエンド・バックエンドまとめて書きたい。JavaScriptオンリーで」なんて場合には最適になるのかもしれません。