Pré-rendu des routes avec réactif-snap

Vous ne souhaitez pas utiliser le rendu côté serveur, mais vous souhaitez tout de même accélérer les performances de votre site React ? Essayez le prérendu.

react-snap est une bibliothèque tierce qui prérend les pages de votre site en fichiers HTML statiques. Cela peut améliorer les temps de première peinture dans votre application.

Voici une comparaison d'une même application avec et sans prérendu, chargée sur une connexion 3G simulée et sur un appareil mobile:

Comparaison côte à côte du chargement. La version utilisant le prérendu se charge 4,2 secondes plus vite.

En quoi est-ce utile ?

Le principal problème de performances des grandes applications monopages est que l'utilisateur doit attendre que le ou les bundles JavaScript qui constituent le site aient fini de se télécharger avant de pouvoir voir un contenu réel. Plus les lots sont volumineux, plus l'utilisateur devra patienter.

Pour résoudre ce problème, de nombreux développeurs optent pour l'approche consistant à afficher l'application sur le serveur au lieu de la démarrer uniquement dans le navigateur. À chaque transition de page/de route, le code HTML complet est généré sur le serveur et envoyé au navigateur, ce qui réduit les délais de première peinture, mais au détriment d'un temps de premier octet plus lent.

Le prérendu est une technique distincte, moins complexe que le rendu sur serveur, mais elle permet également d'améliorer les temps de First Paint dans votre application. Un navigateur sans interface utilisateur (headless) est utilisé pour générer des fichiers HTML statiques de chaque route pendant la création. Ces fichiers peuvent ensuite être expédiés avec les bundles JavaScript nécessaires à l'application.

react-snap

react-snap utilise Puppeteer pour créer des fichiers HTML prérendus de différentes routes dans votre application. Pour commencer, installez-le en tant que dépendance de développement :

npm install --save-dev react-snap

Ajoutez ensuite un script postbuild dans votre package.json :

"scripts": {
  //...
  "postbuild": "react-snap"
}

La commande react-snap s'exécuterait automatiquement chaque fois qu'une nouvelle version des applications est créée (npm build).

La dernière chose que vous devez faire est de modifier le démarrage de l'application. Remplacez le fichier src/index.js par ce qui suit :

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
const rootElement = document.getElementById("root");

if (rootElement.hasChildNodes()) {
  ReactDOM.hydrate(<App />, rootElement);
} else {
  ReactDOM.render(<App />, rootElement);
}

Au lieu d'utiliser uniquement ReactDOM.render pour afficher l'élément React racine directement dans le DOM, cette méthode vérifie si des nœuds enfants sont déjà présents pour déterminer si le contenu HTML a été préaffiché (ou affiché sur le serveur). Dans ce cas, ReactDOM.hydrate est utilisé pour associer des écouteurs d'événements au code HTML déjà créé au lieu de le créer à nouveau.

La compilation de l'application génère désormais des fichiers HTML statiques en tant que charges utiles pour chaque route exploré. Pour voir à quoi ressemble la charge utile HTML, cliquez sur l'URL de la requête HTML, puis sur l'onglet Previews (Aperçus) dans Chrome DevTools.

Comparaison avant/après. La photo d&#39;après montre que le contenu a été rendu.

Flash du contenu non stylisé

Bien que le code HTML statique soit désormais affiché presque immédiatement, il reste sans style par défaut, ce qui peut entraîner l'affichage d'un "flash de contenu sans style" (FOUC). Cela peut être particulièrement visible si vous utilisez une bibliothèque CSS-in-JS pour générer des sélecteurs, car le bundle JavaScript doit terminer son exécution avant que des styles puissent être appliqués.

Pour éviter cela, le CSS essentiel, ou la quantité minimale de CSS nécessaire pour que la page initiale s'affiche, peut être intégré directement dans le <head> du document HTML. react-snap utilise en interne une autre bibliothèque tierce, minimalcss, pour extraire tout CSS critique pour différents parcours. Pour ce faire, spécifiez les éléments suivants dans votre fichier package.json :

"reactSnap": {
  "inlineCss": true
}

Si vous examinez l'aperçu de la réponse dans les outils pour les développeurs Chrome, vous verrez désormais la page stylisée avec le CSS critique intégré.

Comparaison avant/après. La photo d&#39;après montre que le contenu a été affiché et stylisé grâce au CSS critique intégré.

Conclusion

Si vous n'utilisez pas de routes de rendu côté serveur dans votre application, utilisez react-snap pour préafficher du code HTML statique auprès de vos utilisateurs.

  1. Installez-le en tant que dépendance de développement et commencez avec les paramètres par défaut uniquement.
  2. Utilisez l'option expérimentale inlineCss pour intégrer le CSS critique si elle fonctionne pour votre site.
  3. Si vous utilisez le fractionnement du code au niveau des composants dans des routes, veillez à ne pas pré-afficher un état de chargement auprès de vos utilisateurs. Le fichier react-snap README explique ce point plus en détail.