ReactJSサーバー側レンダリングとクライアント側レンダリング


120

私はReactJSを研究し始めたばかりで、ページをレンダリングする2つの方法(サーバー側とクライアント側)を提供することがわかりました。しかし、一緒に使う方法がわかりません。アプリケーションを構築する方法は2つありますか、それとも一緒に使用できますか?

それを一緒に使用できる場合、その方法-サーバー側とクライアント側で同じ要素を複製する必要がありますか?または、サーバーでアプリケーションの静的な部分を構築し、クライアント側で動的な部分を構築できます。事前にレンダリングされたサーバー側への接続はありませんか?


1
短い答え、いいえ-分離して静的HTMLを送信し、クライアントレンダーで完全に変更できます。私の答えに詳細を追加しました。
吉良

回答:


108

特定のWebサイト/ Webアプリケーションに対して、クライアント側サーバー、またはその両方で反応を使用できます。

クライアント側

ここでは、ブラウザーで完全にReactJSを実行しています。これは最も単純な設定であり、ほとんどの例が含まれています(http://reactjs.orgの例を含む)。サーバーによってレンダリングされる最初のHTMLはプレースホルダーであり、すべてのスクリプトが読み込まれると、UI全体がブラウザーにレンダリングされます。

サーバ側

ここでは、ReactJSをサーバー側のテンプレートエンジン(jade、ハンドルバーなど)と考えてください。サーバーによってレンダリングされたHTMLには本来あるべきUIが含まれており、スクリプトのロードを待つ必要はありません。あなたのページは、検索エンジンによってインデックスを作成することができます(JavaScriptを実行しない場合)。

UIはサーバーでレンダリングされるため、イベントハンドラーはどれも機能せず、対話性はありません(静的ページがあります)。

両方とも

ここでは、最初のレンダリングはサーバー上にあります。したがって、ブラウザが受信するHTMLには、本来あるべきUIがあります。スクリプトがロードされると、仮想DOMが再度レンダリングされ、コンポーネントのイベントハンドラーがセットアップされます。

ここでpropsは、サーバーでのレンダリングに使用したものとまったく同じ仮想DOM(ルートReactJSコンポーネント)を確実に再レンダリングする必要があります。そうしないと、ReactJSはサーバー側とクライアント側の仮想DOMが一致しないと文句を言います。

ReactJSは再レンダリング間で仮想DOMを比較するため、実際のDOMは変更されません。イベントハンドラーのみが実際のDOM要素にバインドされます。


1
「両方」の場合、サーバーレンダリング用に1つ、クライアントでこのDOMを再現するために1つ、同じコードを2回書く必要がありますか?
Simcha

10
同じコードを2回実行する必要があります。サーバー上とクライアント上で1回ずつ。ただし、これを考慮するためにコンポーネントを作成する必要があります。たとえばcomponentWillMount()、クライアントとサーバーの両方を実行するため、では非同期データのフェッチを行わないでください。同じ出力が得られるようにするには、サーバーでデータを事前にフェッチし、クライアントでの初期レンダリングに使用できるようにする戦略も必要です。
Jonny Buchanan 14

3
実行中のコードがサーバー側とクライアント側のどちらにあるかを確認してtypeof window == "undefined"から、それに応じてデータをフェッチすることもできます。
Gautham Badhrinathan 2014

あなたの実装に合った例へのリンクはありますか?
Sawtaytoes 2016

1
@IanW通常、この場合、サーバーから返されるHTMLは非常に「最小限の骨」であり、JavaScriptとスタイルをインポートし、<div>Reactが書き込むを含むだけです。
Matt Holland

48

画像ソース:Walmart Labs Engineering Blog

SSR

CSR

注意:SSR(サーバー側レンダリング)、CSR(クライアント側レンダリング)。

主な違いは、SSRでは、サーバーがクライアントのブラウザーに応答するときに、レンダリングされるページのHTMLが含まれることです。SSRを使用すると、ページのレンダリングが速くなることにも注意してください。JSファイルがダウンロードされ、ブラウザーがReactを実行するまで、ページはユーザーとの対話の準備ができていません。

1つの欠点は、SSR TTFB(最初のバイトまでの時間)がわずかに長くなる可能性があることです。当然のことながら、サーバーはHTMLドキュメントの作成に時間がかかるため、サーバーの応答サイズが大きくなります。


4

私は実際に同じ研究をかなり疑問に思っていましたが、あなたが探している答えはコメントで与えられていましたが、私はそれがより顕著になるはずなので、私はこの投稿を書いています(私が思いついたら更新します)私が解決策をアーキテクチャ的に少なくとも疑問視するので、より良い方法です)。

両方の方法を念頭に置いてコンポーネントを作成する必要があるため、基本的にはifスイッチをどこにでも配置して、クライアントまたはサーバーのどちらにいるかを判別し、DBクエリ(またはサーバー上で適切なもの)またはREST呼び出し(クライアント)。次に、データを生成してクライアントに公開するエンドポイントを作成する必要があります。

繰り返しますが、よりクリーンなソリューションについて学ぶことを嬉しく思います。


2

アプリケーションを構築する方法は2つありますか、それとも一緒に使用できますか?

併用できます。

それを一緒に使用できる場合、その方法-サーバー側とクライアント側で同じ要素を複製する必要がありますか?または、サーバーでアプリケーションの静的な部分を構築し、クライアント側で動的な部分を構築できます。事前にレンダリングされたサーバー側への接続はありませんか?

同じレイアウトをレンダリングして、リフローと再描画の操作を回避し、ちらつきや点滅を少なくすると、ページがスムーズになります。ただし、これは制限ではありません。SSR html(何か電極が応答時間を短縮するために行う処理)を、CSR(クライアント側のレンダリング)によって上書きされる静的htmlを送信することもできます。

SSRから始めたばかりの場合は、シンプルに開始することをお勧めします。SSRは非常に複雑になりがちです。サーバー上でhtmlをビルドすると、ウィンドウ、ドキュメント(これらはクライアント上にあります)などのオブジェクトへのアクセスが失われ、非同期操作(そのまま)を組み込むことができなくなり、一般にコードSSR互換性を得るための多くのコード編集が失われます( bundle.jsをパックするには、webpackを使用する必要があるためです。CSSインポート、要求vsインポートのようなものは突然あなたを噛み始めます(これはwebpackのないデフォルトのReactアプリの場合ではありません)。

SSRの一般的なパターンは次のようになります。リクエストを処理するExpressサーバー:

const app = Express();
const port = 8092;

// This is fired every time the server side receives a request
app.use(handleRender);
function handleRender(req, res) {
    const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
    console.log('fullUrl: ', fullUrl);
    console.log('req.url: ', req.url);

    // Create a new Redux store instance
    const store = createStore(reducerFn);

    const urlToRender = req.url;
    // Render the component to a string
    const html = renderToString(
        <Provider store={store}>
            <StaticRouter location={urlToRender} context={{}}>
                {routes}
            </StaticRouter>
        </Provider>
    );
    const helmet = Helmet.renderStatic();

    // Grab the initial state from our Redux store
    const preloadedState = store.getState();

    // Send the rendered page back to the client
    res.send(renderFullPage(helmet, html, preloadedState));
}

SSRで始めている人への私の提案は、静的なHTMLを提供することです。CSR SPAアプリを実行することで静的HTMLを取得できます。

document.getElementById('root').innerHTML

SSRを使用する唯一の理由は次のとおりです。

  1. SEO
  2. 読み込みが速い(これを割り引く)

ハック:https : //medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.