web-dev-qa-db-ja.com

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

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

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

101
Simcha

特定のWebサイト/ Webアプリケーションに対して、reactを使用できますclient-sideserver-sideまたはboth

クライアント側

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

サーバ側

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

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

両方

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

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

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

95

画像ソース: Walmart Labs Engineering Blog

SSR

CSR

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

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

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

37
JSON C11

私は実際に同じ研究をかなり不思議に思っていましたが、あなたが探している答えはコメントで与えられていましたが、それはもっと目立つはずだと思うので、この投稿を書いています(これを見つけたら更新します)ソリューションがアーキテクチャ的に少なくとも疑わしいと思うときのより良い方法)。

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

繰り返しますが、よりクリーンなソリューションについて学ぶことができてうれしいです。

3
SGD

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

それらは一緒に使用できます。

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

同じレイアウトをレンダリングして、リフローや再描画の操作を避け、ちらつきや点滅を減らして、ページをより滑らかにすることをお勧めします。ただし、これは制限ではありません。 SSR html(応答時間を短縮するために何か 電極 が行います)を非常にうまくキャッシュできます/ CSRによって上書きされる静的htmlを送信します(クライアント側のレンダリング)。

SSRを始めたばかりの場合は、シンプルに始めることをお勧めします。SSRは非常に複雑になります。サーバー上でhtmlを構築するということは、ウィンドウ、ドキュメント(クライアント上にこれらがあります)などのオブジェクトへのアクセスを失い、非同期操作(すぐに使用可能)を組み込む能力を失い、一般的にコードSSR互換性を得るための多くのコード編集を失います( webpackを使用してbundle.jsをパックする必要があるため)。 CSSインポート、require vs importなどが突然噛みつき始めます(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

1
Kira