Rendu côté serveur avec React

Qu'est-ce que le rendu côté serveur? Comment le faire avec React?

Rendu côté serveur, aussi appeléSSR, est la capacité d'une application JavaScript à effectuer le rendu sur le serveur plutôt que dans le navigateur.

Pourquoi voudrions-nous jamais le faire?

  • il permet à votre site d'avoir un temps de chargement de la première page plus rapide, ce qui est la clé d'une bonne expérience utilisateur
  • c'est essentiel pour le référencement: les moteurs de recherche ne peuvent pas (encore?) indexer efficacement et correctement les applications qui rendent exclusivement côté client. Malgré les dernières améliorations apportées à l'indexation dans Google, il existe également d'autres moteurs de recherche, et Google n'est en aucun cas parfait dans ce domaine. De plus, Google favorise les sites avec des temps de chargement rapides, et devoir charger côté client n'est pas bon pour la vitesse
  • c'est super quand les gens partagent une page de votre site sur les réseaux sociaux, car ils peuvent facilement rassembler les métadonnées nécessaires pour bien partager le lien (images, titre, description ..)

Sans le rendu côté serveur, tout votre serveur est livré avec une page HTML sans corps, juste quelques balises de script qui sont ensuite utilisées par le navigateur pour rendre l'application.

Les applications rendues par le client sont parfaites pour toute interaction utilisateur ultérieure après le chargement de la première page. Le rendu côté serveur nous permet d'obtenir le point idéal au milieu des applications rendues par le client et des applications rendues par le backend: la page est générée côté serveur, mais toutes les interactions avec la page une fois qu'elle a été chargée sont gérées côté client.

Cependant, le rendu côté serveur a aussi son inconvénient:

  • il est juste de dire qu'une simple preuve de concept SSR est simple, mais la complexité de SSR peut croître avec la complexité de votre application
  • le rendu d'une grande application côté serveur peut être assez gourmand en ressources, et sous une forte charge, il pourrait même fournir une expérience plus lente que le rendu côté client, car vous avez un seul goulot d'étranglement

Un exemple très simpliste de ce qu'il faut pour rendre côté serveur une application React

Les configurations SSR peuvent devenir très, très complexes et la plupart des didacticiels seront intégrésRedux,Routeur Reactet bien d'autres concepts dès le départ.

Pour comprendre comment fonctionne SSR, commençons par les bases pour implémenter une preuve de concept.

N'hésitez pas à sauter ce paragraphe si vous souhaitez simplement vous pencher sur les bibliothèques qui fournissent SSR et ne pas vous soucier du travail de base

Pour implémenter le SSR de base, nous allons utiliser Express.

Si vous êtes nouveau dans Express ou avez besoin de rattrapage, consultez mon manuel Express gratuit ici:https://flaviocopes.com/page/ebooks/.

Attention: la complexité du SSR peut croître avec la complexité de votre application. Il s'agit de la configuration minimale pour rendre une application React de base. Pour des besoins plus complexes, vous devrez peut-être faire un peu plus de travail ou également consulter les bibliothèques SSR pour React.

Je suppose que vous avez démarré une application React aveccreate-react-app. Si vous essayez simplement, installez-en un maintenant en utilisantnpx create-react-app ssr.

Accédez au dossier principal de l'application avec le terminal, puis exécutez:

npm install express

Vous avez un ensemble de dossiers dans votre répertoire d'applications. Créez un nouveau dossier appeléserver, puis entrez-y et créez un fichier nomméserver.js.

Suivant lecreate-react-appconventions, l'application vit dans lesrc/App.jsdéposer. Nous allons charger ce composant et le rendre dans une chaîne en utilisantReactDOMServer.renderToString (), qui est fourni parreact-dom.

Vous obtenez le contenu du./build/index.htmlfichier et remplacez le<div id="root"></div>espace réservé, qui est la balise où l'application accroche par défaut, avec `<div id="root">\${ReactDOMServer.renderToString(<App />)}</div>.

Tout le contenu à l'intérieur dubuildLe dossier sera servi tel quel, statiquement par Express.

import path from 'path'
import fs from 'fs'

import express from ‘express’ import React from ‘react’ import ReactDOMServer from ‘react-dom/server’

import App from ‘…/src/App’

const PORT = 8080 const app = express()

const router = express.Router()

const serverRenderer = (req, res, next) => { fs.readFile(path.resolve(’./build/index.html’), ‘utf8’, (err, data) => { if (err) { console.error(err) return res.status(500).send(‘An error occurred’) } return res.send( data.replace( ‘<div id=“root”></div>’, &lt;div id="root"&gt;</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">ReactDOMServer</span>.<span style="color:#a6e22e">renderToString</span>(<span style="color:#f92672">&lt;</span><span style="color:#a6e22e">App</span> <span style="color:#f92672">/&gt;</span>)<span style="color:#e6db74">}</span><span style="color:#e6db74">&lt;/div&gt; ) ) }) } router.use(’^/$’, serverRenderer)

router.use( express.static(path.resolve(__dirname, ‘…’, ‘build’), { maxAge: ‘30d’ }) )

// tell the app to use the above rules app.use(router)

// app.use(express.static(’./build’)) app.listen(PORT, () => { console.log(SSR running on port </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">PORT</span><span style="color:#e6db74">}</span><span style="color:#e6db74">) })

Maintenant, dans l'application client, dans votresrc/index.js, au lieu d'appelerReactDOM.render():

ReactDOM.render(<App />, document.getElementById('root'))

appelerReactDOM.hydrate(), qui est identique mais a la possibilité supplémentaire d'attacher des écouteurs d'événements au balisage existant une fois que React se charge:

ReactDOM.hydrate(<App />, document.getElementById('root'))

Tout le code Node.js doit être transpilé parBabel, car le code Node.js côté serveur ne sait rien de JSX, ni des modules ES (que nous utilisons pour leincludedéclarations).

Installez ces 4 packages:

npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles

ignore-stylesest un utilitaire Babel qui lui dira d'ignorer les fichiers CSS importés à l'aide duimportsyntaxe.

Créons un point d'entrée dansserver/index.js:

require('ignore-styles')

require(’@babel/register’)({ ignore: [/(node_modules)/], presets: [’@babel/preset-env’, ‘@babel/preset-react’] })

require(’./server’)

Générez l'application React, de sorte que le dossier build / soit rempli:

npm run build

et exécutons ceci:

node server/index.js

J'ai dit que c'était une approche simpliste, et c'est:

  • il ne gère pas correctement le rendu des images lors de l'utilisation d'importations, qui nécessitent Webpack pour fonctionner (et ce qui complique beaucoup le processus)
  • il ne gère pas les métadonnées d'en-tête de page, ce qui est essentiel pour le référencement et le partage social (entre autres)

Donc, bien que ce soit un bon exemple d'utilisationReactDOMServer.renderToString()etReactDOM.hydratepour obtenir ce rendu de base côté serveur, ce n'est pas suffisant pour une utilisation dans le monde réel.

Rendu côté serveur à l'aide de bibliothèques

La SSR est difficile à faire correctement, et React n'a aucun moyen de facto de l'implémenter.

Il est encore très discutable si cela vaut la peine, la complication et les frais généraux pour obtenir les avantages, plutôt que d'utiliser une technologie différente pour servir ces pages.Cette discussion sur Reddita beaucoup d'opinions à cet égard.

Lorsque le rendu côté serveur est une question importante, ma suggestion est de s'appuyer sur des bibliothèques et des outils prédéfinis qui ont cet objectif à l'esprit depuis le début.

En particulier, je suggèreNext.jsetGatsby.

Téléchargez mon gratuitManuel React


Plus de tutoriels de réaction: