Facebook の React チームは Server Components をプレビューしました。これにより、開発者はサーバー上で実行されるコードを記述できるようになり、データ アクセスが高速化され、Web ブラウザーでダウンロードする必要があるコードの量が削減されます。
アプリケーションは、コードの大部分をクライアントで実行すべきか、それともサーバーで実行すべきか?これは終わりのない問いであり、技術の進歩に伴い、そのバランスは一方向に傾いたり、また一方向に傾いたりします。初期のWebアプリケーションは主にサーバー上で実行されていました。これは、Webブラウザが基本的なスクリプト機能しか備えていなかったことが一因で、WindowsやMacの巨大なネイティブクライアントアプリケーションに取って代わることが多かったためです。しかし、高速接続、非同期JavaScript、そしてHTML 5の登場により、振り子は再びクライアント側へと傾きました。
その後、AJAX(非同期JavaScriptとXML、後にfetch API)、HTML 5、そして超高速JavaScriptが登場しました。React.jsやAngular.jsといったフレームワークのおかげで、よりリッチなブラウザアプリケーションの構築が容易になりましたが、その代償として、コードの肥大化や、おそらくHTMLの見栄えの悪さ(もし見ていない人がいたら)といった問題もありました。
新たなトレンドはさらに一歩進み、JavaScriptで構築された静的ウェブサイトからマイクロサービスを呼び出して動的コンテンツを提供するという主張が広がっています。Gatsby、Hugo、Next.jsといったJAMStack(JavaScript、API、マークアップ)サイトジェネレーターは、Webサーバーを必要としないWebアプリケーションを作成します。GatsbyとNext.jsはどちらもReact.jsを使用しているため、どちらか一方を選ぶ必要はありません。
Facebookのシニアソフトウェアエンジニアであるダン・アブラモフ氏は、Reactのコードをブラウザにダウンロードするのではなく、サーバー上で実行することの利点について説明している。
何が問題になるのでしょうか?React Server Componentsの紹介記事で、FacebookとReact Coreの開発者であるDan Abramov氏は、ウォーターフォール問題と呼ばれる問題について説明しています。これは、異なるコンポーネントにデータを入力するのに複数の異なるデータベースクエリを必要とするアプリケーションのことです。すべてのデータを1回のJavaScriptフェッチ(彼はFetchAllTheStuffJustInCase()
これをexample関数と呼んでいます)で取得するのは効率的ですが、特に後日設計が変更され、すべてのデータが必要なくなった場合には、見苦しい解決策となります。彼によると、代替案としては、コンポーネントごとに個別にフェッチを行う必要があり、パフォーマンスに影響を与えるとのことです。
早期プレビュー段階にあるサーバーコンポーネントが解決策となる。.server.js ファイル名のコンポーネントは Node.js 上で実行され、サーバー上でフェッチを実行する。低レイテンシとデータベースサーバーへの近接性により、パフォーマンスの問題は克服される。Abramov 氏によると、サーバーコンポーネントで使用される React ライブラリがブラウザーにダウンロードされないことも利点の 1 つだという。同氏の例では、日付をフォーマットするために 21 KB の日付ライブラリを使用した。これは重いソリューションだが、ライブラリはサーバー上に残るため問題にならないと指摘した。.client.js ファイル名のコンポーネントは、従来どおりブラウザーで実行される。テストでは、ページがサーバーコンポーネントを使用するように変換されると、クライアントにプッシュされる JavaScript バンドルのサイズが 29 パーセント削減されることがチームの観測で確認されており、開発が進むにつれてさらに削減されると期待されている。
サーバーコンポーネントはサーバーサイドレンダリングとは異なり、ユーザーがページを移動しても、データが再取得された場合でも、画面がリフレッシュされることはありません。「サーバーコンポーネントはHTMLにレンダリングされません」と、React Dataに携わるローレン・タン氏は説明します。「特別な形式でレンダリングされます。」このフレームワークは、ユーザーインターフェースをバックグラウンドで更新します。クライアント側でもサーバー側でも実行できるファイルを用意することも可能です。実行場所は「共有コンポーネントをインポートしているコンポーネントの種類によって決まります」とタン氏は言います。このようなコンポーネントは、クライアント側で使用する際にオンデマンドでダウンロードされます。
アブラモフ氏によると、サーバーコンポーネントの利点は、コードがバックエンドのリソースに直接アクセスできることだという。開発者は「APIレイヤーにアクセスすることなく、データを直接読み取りたい」場合もあるという。
Reactにサーバーコンポーネントをサポートする新しいライブラリが追加されました。Postgresデータベースサーバーにアクセスするための react-pg、ファイルシステムを操作するための react-fs、サーバーからAPIを呼び出すための react-fetch などです。これらはReact IOライブラリと呼ばれます。
サーバーコンポーネントは、Facebookなどが使用しているランタイムおよびクエリ言語であるGraphQLに取って代わるのでしょうか?「そうではありません」とアブラモフ氏は述べました。「FacebookではサーバーコンポーネントとGraphQLの両方を使用しています」と付け加えましたが、新しいコンポーネントによって、場合によってはGraphQLが不要になる可能性もあると付け加えました。サーバーコンポーネントはGraphQLクエリを読み取ることができます。
Visual Studio Code と Docker を使ったサーバーコンポーネントのデモを試す
今日、多くの開発者がReact.jsやその他の最新のJavaScriptフレームワークをサーバーサイドのウェブアプリケーションと組み合わせています。React Server Componentsの登場により、Reactはよりフルスタックな選択肢となるでしょう。Abramov氏は、「サーバー駆動型のメンタルモデルを備えたモダンなUXを提供します」と述べています。
アブラモフ氏によると、この技術はまだ研究開発段階にあり、チームはNext.jsの開発者と協力中です。まずはデモをダウンロードして試してみることをお勧めします。開発者はこれを広く利用することは推奨されていません(Facebookはそうしているようですが)。アブラモフ氏は、プログラマーが現在のプレビューコンポーネントを本番環境に組み込んだり、コースで教えたりすると、「私たちの研究をオープンに共有することが難しくなる」と不可解な発言をしました。開発者にはRFCを読んでコメントを追加することが推奨されています。
初期の反応は様々です。「サーバーコンポーネントは素晴らしいアイデアで、状況を変えるでしょう」とある人は述べ、別の人は「パフォーマンスのわずかな向上と、これによってプロジェクトにもたらされる複雑さを比べることはできません。特に、このコンポーネントを導入する前に、他に実行できる手段がたくさんあるのですから」とコメントしました。®