blog-hero-img

わかりにくいReactサーバーコンポーネントがこれだけでわかる【ビギナー向け】

pen-icon2025.3.9

この記事は約5分で読めます

Profile Pic

この記事の筆者:三好アキ


🔹 専門用語なしでプログラミングを教えるメソッドに定評があり、1200人以上のビギナーを、最新のフロントエンド開発入門に成功させる。Amazonベストセラー1位を複数回獲得している『はじめてつくるReactアプリ with TypeScript』、『動かして学ぶ!Next.js/React開発入門(翔泳社/2024年)』著者。


Amazon著者ページはこちら → amazon.co.jp/stores/author/B099Z51QF2



🔹 UdemyでReact・JavaScript・Node.jsの入門動画を無料で公開中 → 無料の入門動画


Reactサーバーコンポーネントはわかりにくい

「Reactサーバーコンポーネント」という名前を聞くようになってから数年が経ちます。

しかし「いまいちReactサーバーコンポーネントの仕組みがわからない」と感じている人は多い、というのが私の印象です。

実際に私自身、最初の頃はReactサーバーコンポーネントがどういうものなのかわからないまま使っていました。

わからくても、なんとなく使うことはできるからです。

ネットには、Reactサーバーコンポーネントを紹介する記事がたくさんあります。

かつて私もそういったものに目を通していましたが、そのほとんどは「Reactサーバーコンポーネントのメリット/デメリット」といった、いわば「結果」に触れたものばかりで、私が疑問に思っていた「なぜそうなるのか」、「なぜそのようなメリット/デメリットが出てくるのか」という一段深いところを解きほぐしたもの、さらにそれがビギナー向けにわかりやすく書いてあるものは、ほとんどありませんでした。

そこで本記事では、類似テクノロジーとの比較を通して、Reactサーバーコンポーネントを初心者向けにわかりやすく紹介します。

Reactサーバーコンポーネント概略

Reactサーバーコンポーネントは2020年に発表されたReactの新しい機能です。

まずNext.jsバージョン13(2022年10月リリース)で利用可能になり、Reactバージョン19(2024年12月リリース)ではReact本体からも安定版として提供が始まりました。

ReactフレームワークであるNext.jsでの提供が先行していたことから、現時点では依然としてNext.jsがReactサーバーコンポーネントをスムーズに使うためのほぼ唯一の選択肢です。この点は後ほど確認をします。

Reactサーバーコンポーネントとはその名前のとおり、サーバー側でReactが動いているということですが、従来のReactコンポーネント(=Reactクライアントコンポーネント、くわしくはこちら)とは何が違い、どのようなメリット/デメリットがあるのでしょうか。

Reactサーバーコンポーネント以前のテクノロジー

RSC(React Server Components)は名前がSSR(Server Side Rendering)と似ています。

しかし、SSRのわかりやすい比較対象はSPA(Single Page Application)です。

これらのテクノロジーの名が広まったのは、SPAが2010年ごろ、SSRが2016年ごろ、RSCが2022年ごろですが、新しい技術というのはその前にあったテクノロジーが抱えていた問題を改善したものとして出てきます。

登場時期
MPA(マルチ・ページ・アプリケーション) SPA以前(2000年ごろ)
SPA(シングル・ページ・アプリケーション) 2010年ごろ
SSR(サーバー・サイド・レンダリング) 2016年ごろ
RSC(Reactサーバー・コンポーネント) 2022年ごろ

そして多くの場合、新しい技術は必ずしも古い技術を完全に置き換えるものではなく、むしろ補完する形で登場します。

これはそのままSPAとSSRの関係にも当てはまるので、まずこの2つを比較していきましょう。

SPAのメリット・デメリット

SPA(Single Page Application)で多くの人がまず疑問に思うのが、その名前です。

アプリ内に複数のページがあるのに(/home/aboutなど)、なぜ「シングル・ページ」という名前がついているのでしょうか。

これまでにReact + Viteやcreate-react-appなどを使ったことのある人は、フォルダ内にindex.htmlというファイルがあったことに気がついたかもしれません。

SPAはindex.htmlという一枚のHTMLファイル(シングル・ページ)を下敷きとして、JavaScriptで描写を行っています。

ページ移動を実行しているのもJavaScriptで、このメリットはページ移動のスピードが速いことです。

それではSPA以前は、どのようにページ移動を行っていたのでしょうか。

SPA以前の仕組みでは、ページ移動時にはクライアント(ブラウザ)がサーバーにリクエストを行い、HTMLとJavaScriptを受け取って表示するという流れでした。

ページが移動するたびに毎回このやりとりを行うため、ページ表示に時間がかかっていたのです。

(*このような従来型のアプリケーションを、SPA(Single Page Application)の対比としてMPA(Multi Page Application)と呼ぶことがあります。)


SPAでは、ページ描画をJavaScriptがクライアント(ブラウザ)側で行うため、ページ移動のたびにサーバーとやりとりをする必要はなく、ページをすばやく表示できます。

しかしこのマイナス面は、ページの初回表示に時間がかかることです。

サーバーは最初のリクエストがあったとき「からっぽのHTMLファイル(index.html)」と、大量のJavaScriptをクライアントに送ります。まずここで時間がかかります。

それらをクライアントが受け取ったあとには、HTMLファイルを下敷きにしてページをJavaScriptで組み立てる作業が始まりますが、ここでもさらに時間がかかります。

この結果、ブラウザには何もない真っ白なページ(=からっぽのHTMLファイル)がしばらく映っていることになるのです。

「からっぽのHTMLファイル」のコード

SPAの初回リクエスト時に送られてくる「からっぽのHTMLファイル」は次のようなもので、<body>タグ内にはJavaScriptを読み込むコードしかありません。ブラウザで表示する具体的なものが何もないのがわかります。

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta name="description" content="お天気アプリです">
        <title>SPA</title>
    </head>
    <body>
        <div id="root"></div>
        <script type="module" src="/main.js"></script>
    </body>
</html>

SSRのメリット・デメリット

このようなページ初回表示時の問題を解決するために登場したのがSSR(Server Side Rendering)です。

SSRでは初回リクエストがあったとき、HTMLを一部だけすばやく組み立て、これとJavaScriptを送り返します。

送っているものだけを見ると、SPAと同じ「HTML + JavaScript」ですが、このHTMLファイルはSPAのような「からっぽ」のものではなく、サーバー側で一部組み立てたもので、最低限必要なデータが含まれたものです。

クライアント(ブラウザ)は「一部組み立てたHTMLファイル」を直ちに表示することができるので、ユーザー体験はよくなります。

「一部組み立てたHTML」のコード

SPAのHTMLファイルとは異なり<body>タグ内にブラウザで表示できるものがある、つまり「からっぽ」ではないのがわかります。

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta name="description" content="ゲストさん、こんにちは">
        <title>SSR</title>
    </head>
    <body>
        <div id="app">
            <h1>ようこそ!</h1>
            <p>こんにちは、<span id="username">ゲスト</span> さん。</p>
        </div>
        <script type="module" src="/main.js"></script>
    </body>
</html>

とはいえこの時点ではまだ、ブラウザに映っているページは完全なものではありません。

サーバーから送られたJavaScriptを使って、ページを完全なものに組み立てる作業が残っています。

この作業は主に<button><form>といったユーザーとのやりとりが発生するところにJavaScriptをつないでいく工程で、「ハイドレーション」と呼ばれます。

(*ハイドレーションとは「水分補給」という意味です。サーバーから送られてきた「乾いたHTMLの骨組み」に、ダイナミックな機能を付与するJavaScriptを与えて「フレッシュで生気みなぎるもの」へと変えるイメージになります。)


ここで重要な点は、SPAとSSRの最大の違いはこの初回表示時の仕組みだけで、基本的にはSSRもハイドレーションが済んだあとにはSPAになることです。

ページ移動時にサーバーとのやりとりは行われず、JavaScriptでページを描画をします。

このようにSPAとSSRの関係は、「SPAの後継がSSR」、「SPAの進化版がSRR」という直列的なものではなく並列的、あるいは相互補完的なものなのです。

さて、すでに気がついた人もいると思いますが、SSRを使っても「クライアントが使うJavaScriptをとにかくすべて送る」という点は同じです。

この部分に手を加えたものがRSC(React Server Components)になります。

Reactサーバーコンポーネントの仕組み

RSCにおいても、SSRのように初回リクエスト時に「一部組み立てたHTMLファイル」と「JavaScript」を送るという点は同じです(つまりRSCとSSRは一緒に使うことができます)。

しかし送るJavaScriptの量が違います。

ブラウザで必要な量だけにしぼって送るのです。

なぜこのようなことが可能かというと、初回リクエストがあったとき、サーバーはRSCのコードを実行し、この段階でJavaScriptを処理しているからです。

ここでクライアントに送るJavaScriptの量が必要最低限になるよう絞っています。

(*JavaScript削減を実際に確認したい人は、こちらの記事を参考にしてください。)

ではページ移動時にはどうなのでしょうか。

先ほど見たSPAとSSRではサーバーとのやりとりがなく、これがページ移動のスピードが速い理由でした。

実はRSCでは、ページ移動時にはサーバーとのやりとりが発生します。

図を見るとリクエストが送られており、SPA以前(=MPA)に戻ったようですが、大きな違いがあります。

RSCでは「ページの変更箇所だけを部分的に更新する」ということが可能なのです。


MPAでは新しいページを表示するとき、ページは全体がリロードされていました。サーバーから毎回、新しいページに必要なHTMLとJavaScriptを受け取り、それでページを上書きするように表示していたからです。たとえばすべてのページで表示されるヘッダーやフッターも、クライアント側で使いまわされるのではなく、毎回サーバーから送られてきていました。

一方、RSCにおけるページ移動時には、「変更箇所だけを部分的に更新する」という方法が使われます(=Partial Rendering)。

この結果、サーバーから送られてくるものはごく少量で済み、さらにページ全体がリロードされることもなくなります。

サーバーから送られてくるものはHTMLやJavaScriptではなく、最適化・軽量化された「RSC Payload」と呼ばれるものです。

「RSC Payload」のコード

RSC Payloadとは下記のようなものです。HTMLではなくJSON形式のデータであるのがわかります。

{
    "data": {
        "children": [
            {
                "type": "h1",
                "key": null,
                "props": {
                    "children": "Hello, Server Components!"
                }
            },
            {
                "type": "p",
                "key": null,
                "props": {
                    "children": "This is rendered on the server and streamed to the client."
                }
            }
        ]
    },
    "metadata": {
        "status": "complete"
    }
}

Reactサーバーコンポーネントの仕組み(データベース連携時)

はっきりと書いていませんでしたが、ここまで話したRSCの仕組みはすべて、実は「データベースからデータを取得をしない場合のRSCの仕組み」でした。

RSCでポートフォリオサイトやコーポレートサイトといった、「普通のウェブサイト」、「静的なウェブサイト」を作った場合のRSCの仕組みです。

しかしReactアプリケーションでは、「データベースからデータを取得して表示する」というデータベースとの連携作業を行うのが一般的です。

なので、ここからはデータベースがある場合のRSCの仕組みについて見ていきましょう。


まず最初はSPA以前のMPAです。

MPAでは、リクエストがあったときには毎回データベースからデータを取得し、そのデータを組み込んだページをHTMLとJavaScriptで作って、クライアントに送っていました。

これがSPAになると、ページ移動のたびにリクエストを送る必要はなくなりました。

しかしページにおいてデータベースからのデータが必要な場合には、リクエストを送る必要があります。

例えば初回アクセス時に表示するページでデータが必要な場合には、最低でも2回のリクエストが行われるのです。

簡略化のため、図では同一のサーバーに毎回リクエストをしているようになっていますが、実際にはたとえばGoogle Fontsのリクエスト、Googleアナリティクスのリクエストなど、異なるサーバーに対して複数のリクエストが送られています。

SPAにおいてJavaScriptはすべてクライアント側で実行されるため、サーバーから送られてきた「大量のJavaScript」を受け取ったあと、ハイドレーションでHTMLに取り付け、その後fetch()のデータ取得やGoogle Fontsの取得といったリクエストが行われます。

私たちがウェブアプリを開いたとき、ローディングのアニメーションがまず表示されますが、あれはデータ取得が初回リクエストとは別に行われているからです。

loading-spa.png

次はSSRです。

SSRとSPAの違いは初回リクエスト時のみなので、ここでもクライアントからデータ取得のリクエストが送られています。

さて、ここまでSPA、SSRと見てきて気がつくのは、リクエストが複数回行われていることです。

ここをもっと効率化できないかと注目したのがRSCです。

RSCではその名前の通り、Reactはサーバーで実行されるので、このときにデータベースからデータ取得を行なってしまえば効率がよさそうです。

ここだけだと、MPAとの違いは大きくないように見えます。

しかし思い出してもらいたいのは、RSCではページの部分的変更を行えることです。

さらにRSCは、「データを取得しながらクライアントに渡していく」というストリーミング(Streaming)も行えます。

図にすると次のようになっているのです。

たとえばスマートフォンで音楽を聴くとき、mp3化した音源をインターネットからダウンロードする方法と、Spotifyなどのストリーミングサービスを使う方法の2通りがあります。

mp3方式では、一度ダウンロードしてしまえば、ネット環境にいなくても使えます。その音楽がmp3というひとつの完結したもの、いわばパッケージ化されたものとしてまるごとスマートフォンに入っているからです。

一方でストリーミング方式では、音楽再生中にはネット接続が必要になります。「ストリーム(stream)」の意味は「(川のような)流れの途切れないもの」ですが、ストリーミング方式では音楽のデータがスマートフォンに継続的に流れ込んできているからです。

MPAにおけるデータベースからのデータ取得とは、mp3を使ったダウンロード方式に似ています。サーバーはクライアントに、データを一括で送っていたらからです。「完成品」を渡していたのです。

一方でRSCのストリーミングは、「未完成でも、いや一部でもいいから、とにかく早くクライアントに渡していく」というものです。

この結果、クライアント(ブラウザ)には、一部であってもデータがすぐに表示されていくので、ユーザー体験は向上します。


ストリーミングの例を見てみましょう。

たとえばページが「ヘッダー」、「サイドバー」、「ユーザーのリスト」、「履歴履歴」の4つから構成され、それぞれにデータベースから異なるデータが必要だったとします。

streaming-example-1.png

MPAでは、これらのデータはサーバから一括で送られてきていました。

一方RSCでは、ページの部分的更新と、ストリーミングによる継続的なデータ取得が可能なので、ユーザーは流れ込んでくるデータをその都度見ていくことができます。

下図では、データの取得度合を色の濃度で表しています。

streaming-example-2.png

RSCでは部分的更新とストリーミングにより、ひとつのページにはデータの取得度合の異なるコンポーネントが混在します。

この結果ユーザーは、たとえ一部であってもデータをすぐに目にすることができるのです。

RSCの仕組みがわかったので、次はRSCのメリット/デメリットを見ていきましょう。

Reactサーバーコンポーネントのメリット

Reactサーバーコンポーネントの特徴を2つ挙げるとすると、まず「サーバー側で動く」、もうひとつが「レンダリングを1回しか行わない」です。

多くのアプリケーションにはログイン機能がついており、ユーザーのメールアドレスやパスワードといった機密情報を扱うことが一般的ですが、RSCではログイン処理などをすべて、ブラウザよりも安全性の高いサーバー側で行います。

そしてクライアント(ブラウザ)には、Reactのコードを解釈し、レンダリングを実行したあとの結果(RSC Payload)を送ることになり、セキュリティ性が高くなります。

また「レンダリングを1回しか行わない」ということは、レンダリングを制御する必要がないことを意味します。

レンダリングの制御は、長い間React開発のボトルネックのひとつでした。

外部データの取得によって変わりうる、ユーザーの画面の表示をしっかりコントロールする必要があるためです。

しかし「レンダリングを1回しか行わない」という制約があるならば、レンダリングに細かな注意を払う必要はなくなります。

そしてレンダリングを1回しか行わず、そのあとは変化しないとは、つまりユーザーの操作にも反応しないということなので、onClickなどのユーザー操作機能がRSCでは使えないことの理由へとつながってきます。

「サーバー側で動く」、「レンダリングを1回しか行わない」ということの結果として、RSCではデータベースからのデータ取得と操作が、よりダイレクトに、かつより量の少ないコードで行えるようになっています。

(*この点を実際に確認したい人は、こちらの記事を参考にしてください。)

Reactサーバーコンポーネントのデメリット

メリットが多いように見えるRSCですが、もちろんマイナス面もあります。

まずアプリの構造が複雑になることです。RSCはまだ比較的新しいテクノロジーであり、使い方のベストプラクティスが確立されているわけではありません。

さらにアプリ内にRSCとRCCという2種類のコンポーネントが共存するため、それぞれをどのように組み合わせるのかを考える必要もあります。

これは学習コストの高さ、チーム開発における個々のスキル差といったことにもつながり、さらに開発環境構築の難しさにも波及します。

Reactバージョン19からRSCは安定版として提供されていますが、実際に本番環境でRSCを使うとなると、現時点での現実的な選択肢はNext.jsだけになります。

Node.jsのインストールとブラウザだけで基本的に事足りていた従来のRCC開発とは違って、RSCにはバンドラー、ルーター、そしてサーバーの高度な連携が必要になるからです。

しかしすべてのReactアプリに、Next.jsのようなフルスタックフレームワークが必要かといういうと、そういうわけではありません。

例えば社内向けの管理アプリや、データ操作ツールといったものは一般向けのアプリケーションではなく、SEOなどを考慮しなくてもいいので、React + ViteでつくるSPAでも十分でしょう。

一方で、一般向けの大規模アプリでは、パフォーマンス性やセキュリティ、そしてSEOといったことがより重要になるため、Reactフレームワークの利用がより現実的な選択肢となるでしょう。

アプリケーションの規模、SEOの重要性、リソース(時間と、開発チームのスキルレベル)といったことが、どのReact開発ツールを使うかを決める上での大きなファクターとなります。


本記事が、Reactサーバーコンポーネントの理解を深める手助けとなれば幸いです。

Profile Pic

メルマガ配信中
(from 三好アキ/エンジニア)


React、Next.js、TypeScriptなど最新のウェブ開発のお役立ち情報を、ビギナー向けにかみ砕いて無料配信中。
(*配信はいつでも停止できます)