Rendu côté serveur ReactJS vs rendu côté client

120

Je viens de commencer à étudier ReactJS et j'ai découvert qu'il vous donne 2 façons de rendre les pages: côté serveur et côté client. Mais je ne comprends pas comment l'utiliser ensemble. S'agit-il de deux façons distinctes de créer l'application ou peuvent-elles être utilisées ensemble?

Si nous pouvons l'utiliser ensemble, comment le faire - devons-nous dupliquer les mêmes éléments côté serveur et côté client? Ou, pouvons-nous simplement construire les parties statiques de notre application sur le serveur et les parties dynamiques du côté client, sans aucune connexion au côté serveur qui était déjà pré-rendu?

Simcha
la source
1
Réponse courte, NON - vous pouvez découpler, envoyer du code HTML statique et le modifier complètement dans le rendu du client. J'ai ajouté des détails dans ma réponse.
Kira

Réponses:

108

Pour un site Web / une application Web donné, vous pouvez utiliser react soit côté client , côté serveur ou les deux .

Côté client

Ici, vous exécutez complètement ReactJS sur le navigateur. Il s'agit de la configuration la plus simple et comprend la plupart des exemples (y compris ceux sur http://reactjs.org ). Le code HTML initial rendu par le serveur est un espace réservé et toute l'interface utilisateur est rendue dans le navigateur une fois que tous vos scripts sont chargés.

Du côté serveur

Pensez ici à ReactJS comme un moteur de création de modèles côté serveur (comme jade, guidons, etc.). Le HTML rendu par le serveur contient l'interface utilisateur comme il se doit et vous n'attendez pas le chargement des scripts. Votre page peut être indexée par un moteur de recherche (si l'on n'exécute aucun javascript).

Étant donné que l'interface utilisateur est rendue sur le serveur, aucun de vos gestionnaires d'événements ne fonctionnerait et il n'y a pas d'interactivité (vous avez une page statique).

Tous les deux

Ici, le rendu initial est sur le serveur. Par conséquent, le HTML reçu par le navigateur a l'interface utilisateur comme il se doit. Une fois les scripts chargés, le DOM virtuel est à nouveau rendu pour configurer les gestionnaires d'événements de vos composants.

Ici, vous devez vous assurer de restituer exactement le même DOM virtuel (composant racine ReactJS) avec le même propsque celui que vous avez utilisé pour le rendu sur le serveur. Sinon, ReactJS se plaindra que les DOM virtuels côté serveur et côté client ne correspondent pas.

Puisque ReactJS diffère les DOM virtuels entre les re-rendus, le vrai DOM n'est pas muté. Seuls les gestionnaires d'événements sont liés aux éléments DOM réels.

Gautham Badhrinathan
la source
1
Donc, en cas de "both", j'ai besoin d'écrire le même code deux fois "un pour le rendu du serveur, et un pour reproduire ce DOM sur le client? N'est-ce pas?
Simcha
10
Vous devez exécuter le même code deux fois. Une fois sur le serveur et une fois sur le client. Cependant, vous devez écrire vos composants pour en tenir compte - par exemple, vous ne devriez pas faire de récupération de données asynchrone componentWillMount(), car cela exécutera à la fois le client et le serveur. Vous aurez également besoin d'une stratégie pour récupérer les données à l'avance sur le serveur et les rendre disponibles pour le rendu initial sur le client, afin de vous assurer d'obtenir le même résultat.
Jonny Buchanan
3
Vous pouvez également vérifier si le code en cours d'exécution se trouve côté serveur ou côté client en utilisant typeof window == "undefined", puis récupérer vos données en conséquence.
Gautham Badhrinathan
Avez-vous un lien vers un exemple qui correspond à votre implémentation?
Sawtaytoes
1
@IanW Typiquement, dans ce cas, le code HTML renvoyé par le serveur est très simple, il suffit d'importer votre JavaScript et vos styles et de contenir un dans <div>lequel React écrira.
Matt Holland
48

Source de l'image: Blog d'ingénierie de Walmart Labs

SSR

RSE

NB: SSR (Server Side Rendering), CSR (Client Side Rendering).

La principale différence étant qu'avec SSR, la réponse des serveurs au navigateur du client inclut le HTML de la page à rendre. Il est également important de noter que même si, avec SSR, la page s'affiche plus rapidement. La page ne sera pas prête pour l'interaction de l'utilisateur tant que les fichiers JS n'auront pas été téléchargés et que le navigateur n'aura pas exécuté React.

Un inconvénient est que le SSR TTFB (Time to First Byte) peut être légèrement plus long. Naturellement, car le serveur prend un certain temps à créer le document HTML, ce qui augmente à son tour la taille de réponse du serveur.

JSON C11
la source
4

En fait, je me demandais un peu la même recherche et bien que la réponse que vous recherchez ait été donnée dans les commentaires, mais je pense qu'elle devrait être plus importante, c'est pourquoi j'écris cet article (que je mettrai à jour une fois que je pourrai trouver un meilleure façon car je trouve la solution architecturale au moins discutable).

Vous auriez besoin d'écrire vos composants dans les deux sens à l'esprit , mettant ainsi des ifcommutateurs partout pour déterminer si vous êtes sur le client ou le serveur, puis faites soit une requête DB (ou tout ce qui est approprié sur le serveur), soit un appel REST (sur le client). Ensuite, vous devrez écrire des points de terminaison qui génèrent vos données et les exposent au client et c'est parti.

Encore une fois, heureux d'apprendre une solution plus propre.

SGD
la source
2

S'agit-il de deux façons distinctes de créer l'application ou peuvent-elles être utilisées ensemble?

Ils peuvent être utilisés ensemble.

Si nous pouvons l'utiliser ensemble, comment le faire - devons-nous dupliquer les mêmes éléments côté serveur et côté client? Ou, pouvons-nous simplement construire les parties statiques de notre application sur le serveur et les parties dynamiques du côté client, sans aucune connexion au côté serveur qui était déjà pré-rendu?

Il est préférable d'avoir la même mise en page rendue pour éviter les opérations de redistribution et de repeinture, moins de scintillement / clignotements, votre page sera plus lisse. Cependant, ce n'est pas une limitation. Vous pouvez très bien mettre en cache le html SSR (ce que fait Electrode pour réduire le temps de réponse) / envoyer un html statique qui est écrasé par le CSR (rendu côté client).

Si vous ne faites que commencer avec SSR, je recommanderais de commencer simple, SSR peut devenir très complexe très rapidement. Construire du html sur le serveur signifie perdre l'accès à des objets comme la fenêtre, le document (vous les avez sur le client), perdre la capacité d'incorporer des opérations asynchrones (prêtes à l'emploi) et généralement de nombreuses modifications de code pour rendre votre code compatible SSR ( car vous devrez utiliser webpack pour emballer votre bundle.js). Des choses comme les importations CSS, nécessitent vs importation commencent soudainement à vous mordre (ce n'est pas le cas dans l'application React par défaut sans webpack).

Le modèle général de SSR ressemble à ceci. Un serveur Express servant les demandes:

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));
}

Ma suggestion aux gens qui débutent avec SSR serait de servir du HTML statique. Vous pouvez obtenir le code HTML statique en exécutant l'application CSR SPA:

document.getElementById('root').innerHTML

N'oubliez pas que les seules raisons d'utiliser SSR devraient être:

  1. SEO
  2. Charges plus rapides (j'écarterais ceci)

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

Kira
la source