By Rohit Kumar
Voici ce que nous allons construire dans ce tutoriel : une belle carte React comme celle-ci.
Dans ce tutoriel, nous utiliserons le rendu côté serveur pour délivrer une réponse HTML lorsqu’un utilisateur ou un crawler frappe une URL de page. Nous traiterons ces dernières requêtes côté client.
Pourquoi en avons-nous besoin ?
Laissez-moi vous guider vers la réponse.
- Quelle est la différence entre le rendu côté client et le rendu côté serveur ?
- Les inconvénients du rendu de React sur le serveur
- Quand devriez-vous utiliser le Server Side Rendering ?
- SEO
- Améliorer les performances
- React Rendered on Server
- React Rendered on Client’s Browser
- Comment ça marche ? – (4 étapes simples)
- Démarrer en configurant notre application
- Pourquoi avons-nous besoin de compiler les fichiers sources ?
- Copie des fichiers statiques précodés &
- Côté serveur
- src/server.js
- 2. src/template.js
- Le côté client
- src/bundle.js
- src/client.js
- Mettre tout ensemble
- Index.js
- Build & Run
- Prêts à devenir un React Pro ?
- Merci de lire ceci.
Quelle est la différence entre le rendu côté client et le rendu côté serveur ?
Dans le rendu côté client, votre navigateur télécharge une page HTML minimale. Il effectue le rendu du JavaScript et y remplit le contenu.
Le rendu côté serveur, quant à lui, effectue le rendu des composants React sur le serveur. La sortie est un contenu HTML.
Vous pouvez combiner ces deux pour créer une application isomorphe.
Les inconvénients du rendu de React sur le serveur
- Le RSS peut améliorer les performances si votre application est petite. Mais il peut aussi dégrader les performances si elle est lourde.
- Il augmente le temps de réponse (et cela peut être pire si le serveur est occupé).
- Il augmente la taille de la réponse, ce qui signifie que la page prend plus de temps à se charger.
- Il augmente la complexité de l’application.
Quand devriez-vous utiliser le Server Side Rendering ?
Malgré ces conséquences du SSR, il y a certaines situations dans lesquelles vous pouvez et devez l’utiliser.
SEO
Chaque site web veut apparaître dans les recherches. Corrigez-moi si je me trompe.
Malheureusement, les crawlers des moteurs de recherche ne comprennent pas encore/ne rendent pas JavaScript.
Cela signifie qu’ils voient une page blanche, peu importe à quel point votre site est utile.
Beaucoup de gens disent que le crawler de Google rend maintenant JavaScript.
Pour tester cela, j’ai déployé l’application sur Heroku. Voici ce que j’ai vu sur la Google Search Console:
Une page blanche.
C’est la plus grande raison pour laquelle j’ai exploré le rendu côté serveur. Surtout quand il s’agit d’une page de pierre angulaire comme une page de destination, un blog, etc.
Pour vérifier si Google rend votre site, visitez :
Le tableau de bord de la console de recherche > Crawl > Fetch comme Google. Entrez l’URL de la page ou laissez-la vide pour la page d’accueil.
Sélectionnez FETCH AND RENDER. Une fois terminé, cliquez pour voir le résultat.
Améliorer les performances
Dans SSR, les performances de l’application dépendent des ressources du serveur et de la vitesse du réseau de l’utilisateur. Cela le rend très utile pour les sites à fort contenu.
Par exemple, disons que vous avez un téléphone mobile de prix moyen avec une vitesse Internet lente. Vous essayez d’accéder à un site qui télécharge 4MB de données avant que vous puissiez voir quoi que ce soit.
Seriez-vous capable de voir quoi que ce soit sur votre écran dans les 2 à 4 secondes ?
Vous visiteriez à nouveau ce site ?
Je ne pense pas.
Une autre amélioration majeure est le temps de première interaction avec l’utilisateur. C’est la différence de temps entre le moment où un utilisateur frappe l’URL et le moment où il voit le contenu.
Voici la comparaison. Je l’ai testé sur un Mac de développement.
React Rendered on Server
Le temps de première interaction est de 300ms. L’hydrate se termine à 400ms. L’événement de chargement se termine à 500ms environ. Vous pouvez le constater en consultant l’image ci-dessus.
React Rendered on Client’s Browser
Le premier temps d’interaction est de 400ms. L’événement de chargement sort à 470ms.
Le résultat parle de lui-même. Il y a une différence de 100ms dans le temps de première interaction avec l’utilisateur pour une si petite application.
Comment ça marche ? – (4 étapes simples)
- Créer un Redux Store frais à chaque demande.
- Optionnellement dispatcher quelques actions.
- Gagner l’état hors du Store et exécuter SSR.
- Envoyer l’état obtenu à l’étape précédente avec la réponse.
Nous utiliserons l’état passé dans la réponse pour créer l’état initial côté client.
Avant de commencer, clonez/téléchargez l’exemple complet depuis Github et utilisez-le comme référence.
Démarrer en configurant notre application
D’abord, ouvrez votre éditeur et votre shell préféré. Créez un nouveau dossier pour votre application. Commençons.
npm init --yes
Remplir les détails. Après la création de package.json
, copiez-y les dépendances et les scripts ci-dessous.
Installez toutes les dépendances en exécutant :
npm install
Vous devez configurer Babel et webpack pour que notre script de construction fonctionne.
Babel transforme ESM et react en code compris par Node et le navigateur.
Créez un nouveau fichier .babelrc
et mettez-y la ligne ci-dessous.
{ "presets": }
webpack regroupe notre app et ses dépendances dans un seul fichier. Créez un autre fichier webpack.config.js
avec le code suivant dedans:
const path = require('path');module.exports = { entry: { client: './src/client.js', bundle: './src/bundle.js' }, output: { path: path.resolve(__dirname, 'assets'), filename: ".js" }, module: { rules: }}
Le processus de construction produit deux fichiers:
-
assets/bundle.js
– application côté client pur. -
assets/client.js
– compagnon côté client pour SSR.
Le dossier src/
contient le code source. Les fichiers compilés Babel vont dans views/
. Le répertoire views
sera créé automatiquement s’il n’est pas présent.
Pourquoi avons-nous besoin de compiler les fichiers sources ?
La raison est la différence de syntaxe entre ESM & CommonJS. En écrivant React et Redux, nous utilisons fortement import et export dans tous les fichiers.
Malheureusement, ils ne fonctionnent pas dans Node. C’est là que Babel vient à la rescousse. Le script ci-dessous indique à Babel de compiler tous les fichiers dans le répertoire src
et de mettre le résultat dans views.
"babel": "babel src -d views",
Maintenant, Node peut les exécuter.
Copie des fichiers statiques précodés &
Si vous avez déjà cloné le dépôt, copiez à partir de celui-ci. Sinon, téléchargez le fichier ssr-static.zip depuis Dropbox. Extrayez-le et conservez ces trois dossiers à l’intérieur de votre répertoire app. Voici ce qu’ils contiennent.
- React
App
et les composants résident danssrc/components
. - Fichiers Redux dans
src/redux/
. -
assets/ & media/
: Contenir les fichiers statiques tels questyle.css
et les images.
Côté serveur
Créer deux nouveaux fichiers nommés server.js
et template.js
à l’intérieur du dossier src/
.
src/server.js
La magie se produit ici. C’est le code que vous avez cherché.
import React from 'react';import { renderToString } from 'react-dom/server';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';module.exports = function render(initialState) { // Model the initial state const store = configureStore(initialState); let content = renderToString(<Provider store={store} ><App /></Provider>); const preloadedState = store.getState(); return { content, preloadedState };};
Au lieu de rendre notre application, nous devons l’envelopper dans une fonction et l’exporter. La fonction accepte l’état initial de l’application.
Voici comment cela fonctionne.
- Passe
initialState
àconfigureStore()
.configureStore()
renvoie une nouvelle instance de Store. Maintenez-la à l’intérieur de la variablestore
. - Appelle la méthode
renderToString()
, en fournissant notre App en entrée. Elle rend notre app sur le serveur et retourne le HTML produit. Maintenant, la variablecontent
stocke le HTML. - Sortir l’état du Redux Store en appelant
getState()
surstore
. Gardez-le dans une variablepreloadedState
. - Retournez les
content
etpreloadedState
. Nous les passerons à notre modèle pour obtenir la page HTML finale.
2. src/template.js
template.js
exporte une fonction. Elle prend title
, state
et content
en entrée. Elle les injecte dans le modèle et renvoie le document HTML final.
Pour transmettre l’état, le modèle attache state
à window.__STATE__
à l’intérieur d’une balise <scri
pt>.
Maintenant vous pouvez lire state
du côté client en accédant à window.__STATE__
.
Nous incluons également l’application côté client du compagnon SSR assets/client.js
dans une autre balise de script.
Si vous demandez la version client pure, elle ne met que assets/bundle.js
à l’intérieur de la balise de script.
Le côté client
Le côté client est assez simple.
src/bundle.js
C’est ainsi que vous écrivez l’enveloppement React et Redux Provider
. C’est notre pure application côté client. Pas d’astuces ici.
import React from 'react';import { render } from 'react-dom';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';const store = configureStore();render( <Provider store={store} > <App /> </Provider>, document.querySelector('#app'));
src/client.js
Cela vous semble familier ? Oui, il n’y a rien de spécial sauf window.__STATE__.
Tout ce que nous devons faire est de récupérer l’état initial de window.__STATE__
et de le passer à notre fonction configureStore()
comme état initial.
Regardons notre nouveau fichier client:
import React from 'react';import { hydrate } from 'react-dom';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';const state = window.__STATE__;delete window.__STATE__;const store = configureStore(state);hydrate( <Provider store={store} > <App /> </Provider>, document.querySelector('#app'));
Regardons les changements:
- Remplacer
render()
parhydrate()
.hydrate()
est identique àrender()
mais est utilisé pour hydrater les éléments rendus parReactDOMServer
. Il garantit que le contenu est le même sur le serveur et le client. - Lire l’état de l’objet global de fenêtre
window.__STATE__
. Stockez-le dans une variable et supprimez lewindow.__STATE__
. - Créer un nouveau magasin avec
state
comme initialState.
Tout est fait ici.
Mettre tout ensemble
Index.js
C’est le point d’entrée de notre application. Il gère les requêtes et le templating.
Il déclare également une variable initialState
. Je l’ai modélisée avec les données du assets/data.json
fichier. Nous la passerons à notre fonction ssr()
.
Note : En faisant référence à un fichier qui est à l’intérieur de src/
à partir d’un fichier à l’extérieur de src/
, utilisez le require()
normal et remplacez src/
par views/
. Vous connaissez la raison (compilation Babel).
Routing
-
/
: Page d’accueil avec rendu serveur par défaut. -
/client
: Exemple de rendu côté client pur. -
/exit
: Bouton d’arrêt du serveur. Disponible uniquement en développement.
Build & Run
Il est temps de construire et d’exécuter notre application. Nous pouvons le faire avec une seule ligne de code.
npm run build && npm run start
Maintenant, l’application s’exécute à http://localhost:3000.
Prêts à devenir un React Pro ?
Je commence une nouvelle série à partir de lundi prochain pour faire flamber vos compétences React, immédiatement.
Merci de lire ceci.
Si vous l’aimez et que vous le trouvez utile, suivez-moi sur Twitter & Webflow.