Le 2021 JavaScript Full-Stack Bootcamp est MAINTENANT OUVERT POUR LES INSCRIPTIONS !
Le Server Side Rendering, également 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 ?
- cela 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 effectuent un rendu exclusivement côté client. Malgré les dernières améliorations apportées à l’indexation par Google, il existe aussi d’autres moteurs de recherche, et Google n’est de toute façon pas parfait dans ce domaine. En outre, Google favorise les sites avec des temps de chargement rapides, et avoir à charger côté client n’est pas bon pour la vitesse
- c’est génial quand les gens partagent une page de votre site sur les médias sociaux, car ils peuvent facilement rassembler les métadonnées nécessaires pour partager joliment le lien (images, titre, description….)
Sans Server Side Rendering, tout ce que votre serveur expédie est 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 excellentes à toute interaction ultérieure de l’utilisateur après le chargement de la première page. Le Server Side Rendering nous permet d’obtenir le sweet spot au milieu des apps à rendu client et des apps à rendu arrière : 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 traitées côté client.
Cependant, le rendu côté serveur a aussi son inconvénient :
- il est juste de dire qu’une preuve de concept SSR simple, mais la complexité du SSR peut croître avec la complexité de votre application
- le rendu d’une grosse 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, puisque vous avez un seul goulot d’étranglement
Un exemple très simpliste de ce qu’il faut pour effectuer le rendu côté serveur d’une application React
Les configurations SSR peuvent devenir très, très complexes et la plupart des tutoriels intégreront Redux, React Router et de nombreux autres concepts dès le début.
Pour comprendre comment SSR fonctionne, commençons par les bases pour mettre en œuvre une preuve de concept.
N’hésitez pas à sauter ce paragraphe si vous voulez juste examiner les bibliothèques qui fournissent SSR et ne pas vous embêter avec le travail de base
Pour mettre en œuvre SSR de base, nous allons utiliser Express.
Si vous êtes nouveau à Express, ou si vous avez besoin de rattrapage, consultez mon manuel gratuit sur Express ici : https://flaviocopes.com/page/ebooks/.
Avertissement : la complexité de 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 commencé une application React avec create-react-app
. Si vous essayez juste, installez-en une maintenant en utilisant npx create-react-app ssr
.
Allez dans le dossier principal de l’app avec le terminal, puis exécutez :
npm install express
Vous avez un ensemble de dossiers dans votre répertoire app. Créez un nouveau dossier appelé server
, puis allez dedans et créez un fichier nommé server.js
.
Suivant les conventions create-react-app
, l’app vit dans le fichier src/App.js
. Nous allons charger ce composant, et le rendre en une chaîne en utilisant ReactDOMServer.renderToString(), qui est fourni par react-dom
.
Vous obtenez le contenu du fichier ./build/index.html
, et remplacez le placeholder <div></div>
, qui est la balise où l’application s’accroche par défaut, par `<div>${ReactDOMServer.renderToString(<App />)}</div>
.
Tout le contenu à l’intérieur du dossier build
va être 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 = 8080const 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></div>', `<div>${ReactDOMServer.renderToString(<App />)}</div>` ) ) })}router.use('^/$', serverRenderer)router.use( express.static(path.resolve(__dirname, '..', 'build'), { maxAge: '30d' }))// tell the app to use the above rulesapp.use(router)// app.use(express.static('./build'))app.listen(PORT, () => { console.log(`SSR running on port ${PORT}`)})
Maintenant, dans l’application cliente, dans votre src/index.js
, au lieu d’appeler ReactDOM.render()
:
ReactDOM.render(<App />, document.getElementById('root'))
appelle ReactDOM.hydrate()
, qui est le même mais qui a la capacité 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 transposé par Babel, car le code Node.js côté serveur ne connaît rien à JSX, ni aux modules ES (que nous utilisons pour les déclarations include
).
Installer ces 4 paquets:
npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles
ignore-styles
est un utilitaire Babel qui lui indiquera d’ignorer les fichiers CSS importés en utilisant la syntaxe import
.
Créons un point d’entrée dans server/index.js
:
require('ignore-styles')require('@babel/register')({ ignore: , presets: })require('./server')
Construisons l’application React, afin que le dossier build/ soit peuplé :
npm run build
et exécutons ceci:
node server/index.js
J’ai dit que c’était une approche simpliste, et ça l’est :
- elle ne gère pas le rendu des images correctement lors de l’utilisation d’imports, qui ont besoin de Webpack pour fonctionner (et qui complique beaucoup le processus)
- elle ne gère pas les métadonnées d’en-tête de page, qui sont essentielles pour le référencement et le partage social (entre autres choses)
Alors que c’est un bon exemple d’utilisation de ReactDOMServer.renderToString()
et ReactDOM.hydrate
pour 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 en utilisant des bibliothèques
Le RSS est difficile à faire correctement, et React n’a pas de moyen de facto de l’implémenter.
C’est encore très discutable si cela vaut la peine, la complication et la surcharge pour obtenir les avantages, plutôt que d’utiliser une technologie différente pour servir ces pages. Cette discussion sur Reddit a beaucoup d’opinions à cet égard.
Lorsque le Server Side Rendering est une question importante, ma suggestion est de s’appuyer sur des bibliothèques et des outils pré-faits qui ont eu cet objectif en tête depuis le début.
En particulier, je suggère Next.js et Gatsby.
Téléchargez mon React Handbook gratuit
Le 2021 JavaScript Full-Stack Bootcamp EST MAINTENANT OUVERT AUX INSCRIPTIONS JUSQU’AU MARDI PROCHAIN ! Ne manquez pas cette opportunité, inscrivez-vous AUJOURD’HUI !
Plus de tutoriels react :
- VS Code setup for React development
- React Concept : Immutabilité
- Comment retourner plusieurs éléments en JSX
- React Portals
- Comment rendre du HTML en React
- La feuille de route pour apprendre React
- Doit-on utiliser jQuery ou React ?
- Comment utiliser le hook React useRef
- React Router, comment obtenir des données depuis une route dynamique
.