本セッションの登壇者
セッション動画
スライド
私はNode.jsの一般社団法人 Japan Node.js Associationの理事をしています古川と申します。また、JSConf JPのオーガナイザーもしており、今年も開催する予定ですのでぜひよろしくお願いします。
React Server Componentsとは
さっそくですが、React Server Componentsについて話をしようと思います。
React Server Componentsは1年くらい前にちょっと話題になっていたかと思うのですが、これ自体が何かと聞かれてパッとわかる人はまだ多くないのかなと思います。簡単にいうとブラウザとサーバで処理の役割分担ができるようになるコンポーネントのことです。処理の役割分担とは、サーバが得意なことはサーバのコンポーネントにやらせて、クライアントが得意なことはクライアントのコンポーネントにやらせる、というこれまでにはないようなコンポーネントの使い方になると思います。
ここには書いていないのですが、サーバサイドレンダリングとかクライアントサイドレンダリングという言葉と混同しやすいので気をつけていただきたいです。サーバサイドレンダリングとは、サーバサイドでHTMLをまるっと作ってクライアントに渡すというものです。逆にクライアントサイドレンダリングは、クライアントサイドでHTMLをまるっと作ってしまうもので、今まではこのようなAll or nothingな状態だったのが、これからはグラデーションにできるというように認識していただければ、そこまで間違いではないです。
このように、React ComponentのTreeがあるとして、Component Treeの内部でサーバの処理とクライアントの処理をまぜこぜにできる、これが新しいところです。
サーバが得意なことは、たとえばデータベースから値を読み込んだり、ファイルを読んだり書いたりすることで、苦手なことはCPUを専有する処理やブラウザAPIと協調することです。逆にクライアントはブラウザAPIとの協調は得意ですが、一方で巨大なJavaScriptファイルやnpmからのファイルをバンドルしたものを読み込むと遅延が大きくなるため、ファイルサイズが増大するような、過多な複雑な処理は苦手としています。
なので、React Server Componentsを理解するうえでの一番のキーワードは適材適所です。サーバサイドとクライアントサイド双方で、得意分野と苦手分野を移譲しあいながらレンダリングできるようになる、これが新しい考え方です。
ただし実際にはReact Server Componentsが「レンダリングする」といってしまうと語弊があります。サーバサイドレンダリング(SSR)とは違い、レンダリングまでするわけではないので、このあたりについて細かく説明したいところですが、時間もないのでここはいったん忘れて、SSRではないということだけ認識しておいてください。
現時点のReact Componentsは基本的にすべてClient Componentsに該当していて、これに加えてあたらしくServer Componentsという概念が出てきたので解説します。
React Server Componentsのメリット
Server Componentsではたとえばデータベースにアクセスするなどの処理をして、Client ComponentsではブラウザAPIとの協調などの処理をして、まぜこぜにして処理ができる、と最初に説明しました。
もう一度メリットを交えて説明します。Server Componentsでデータベースに直接アクセスできると、まず「距離的に近い」ことがメリットです。データベースに直接アクセスせず、たとえばClient ComponentsからPublicなAPIをインターネット経由でリクエストして結果を取得しようとすると、どうしても距離があるのでリクエストしてレスポンスが返るまでのレイテンシが懸念されます。
また他の例として、npmモジュールで巨大なサイズのライブラリをバンドルしなければいけないとしても、サーバサイドでしか使わないライブラリであれば、それはクライアントサイド用にバンドルしなくてよくなります。
メリットを整理すると、クライアントから距離が遠いデータベースやバックエンドのAPIを呼び出すよりも、距離的に近いサーバ側で呼び出せるので手早く情報を取得することができます。また、巨大なnpmモジュールはクライアントサイドのコードにバンドルする必要がなくなり、サーバ側で実行して結果だけを返すことで、クライアントサイドのJavaScriptの肥大化を防ぐことができます。よって、クライアントサイドではバンドルサイズが小さくなってロード時間を軽減できるというメリットがあります。
React Server Componentsの実際の動き
React Server Componentsを実際にどうやって書くのかというと、コンポーネントのファイル名にServer Componentsは.server.jsx
、Client Componentsは.client.jsx
と明記することになっています。ここで注意しなければいけないのは、Server ComponentsからClient Componentをインポートできるものの、逆にClient ComponentsからServer Componentsをインポートできないということです。そのため、うまく併用して書く必要があります。
React Componentsは最終的にHTMLになりますが、React Server Componentsはその中間表現であるRSCツリーを作ります。RSCツリーは実際にはJSON形式で、生成されたRSCツリーは適宜ブラウザに渡されます。
Client Componentsはサーバサイドではモジュールが解決されず、モジュールの参照だけがブラウザに渡されます。一方でServer Componentsはサーバサイドの処理が終わるとHTMLに近い情報が生成されてブラウザに渡されます。
ここからは少しマニアックなお話ですが、RSC TreeのJSONが生成されたら、ストリームとしてブラウザに送られ、解決できたところからReact Componentsがあてはめられていく(レンダリングされていく)というイメージです。解決できたところから、JSONからHTMLに再生されていくということになり、これがReact Server Componentsの実際の動きの主要な部分です。
Reactのレンダリング方法の今後
今後のお話をすると、まずサーバサイドとクライアントサイドの適材適所の分担がさらに求められるようになります。とくにSSR周りは非常に新しい変革が起きそうで、個人的にはすごくおもしろいところだと思っています。今まではサーバサイドレンダリングであればサーバ側でHTMLをすべてレンダリングするか、そうでなければクライアント側でHTMLをすべてレンダリングするかのどちらかしかできませんでしたが、これからは適材適所で一部のみサーバ側でレンダリングするということができるようになります。
ほかにも今回は説明しませんでしたが、Streaming HTMLやSelective Hydrationなどの新しいReactの登場人物がまだまだ登場する予定になっています。言い方を選ばなければどんどん設計自体は複雑になっていくのですが、それを楽しめるようになってくるとReactの新しいサーバーサイドレンダリングの世界を楽しめるようになるのではないかと思っています。
本日はありがとうございました。