• Contact us
  • Documentation
  • Login
Watch a demoFree trial
Blog
Blog
BlogProduitÉtudes de casNouvellesPerspectives
Blog

Maîtrise les composants serveur React grâce à notre guide complet

JavaScriptnode.jsperformance
01 janvier 2025
Partager
Cette page a été rédigée en anglais par nos experts, puis traduite par une IA pour vous y donner accès rapidement! Pour la version originale, c’est par ici.

React a complètement transformé la façon dont nous créons les interfaces utilisateur en introduisant une conception basée sur les composants qui favorise l'efficacité et la réutilisabilité. Sa méthode déclarative et sa structure basée sur les composants ont gagné en popularité auprès des développeurs. Mais à mesure que tes projets gagnent en complexité, tu pourrais rencontrer des problèmes de performances liés aux méthodes de rendu et de récupération des données.

Dans les méthodes traditionnelles de rendu côté client, tu dépends du navigateur pour exécuter du JavaScript afin d’afficher l’interface utilisateur initiale. Cela peut entraîner des retards de chargement sur les appareils aux ressources limitées. La récupération de données à partir d’une interface de programmation d’application (API) ajoute une charge supplémentaire à ces appareils, ce qui peut causer un décalage dans l’affichage du contenu et offrir des interactions utilisateur loin d’être idéales.

Les composants serveur offrent une solution à ces obstacles en permettant le rendu des composants sur le serveur. Cela permet au serveur de diffuser les composants vers le côté client, ce qui améliore les performances et les processus de récupération des données, puisque tout le traitement s'effectue sur le serveur et non sur les appareils des utilisateurs.

Dans cet article, tu découvriras comment les méthodes de rendu de React ont évolué au fil du temps, ainsi que les inconvénients liés à l'utilisation de React Suspense et du rendu côté serveur (SSR). De plus, tu en apprendras davantage sur les composants serveur React (RSC) et sur la manière dont ils résolvent ces problèmes.

Comprendre les stratégies de rendu traditionnelles de React

Avant d'aborder les RSC, il est utile de comprendre les stratégies de rendu antérieures, telles que React Suspense et le SSR.

React Suspense

React Suspense a été introduit pour gérer le rendu asynchrone dans les applications React. Il permet aux composants de « suspendre » le rendu jusqu’à ce que certaines conditions soient remplies, comme la récupération de données ou le fractionnement de code. Voici quelques-uns des avantages de Suspense :

  • Une expérience utilisateur améliorée. Suspense te permet d'utiliser des espaces réservés pour tes composants, ce qui facilite l'affichage d'indicateurs de chargement pendant la récupération des données. Cela permet d'éviter l'affichage d'un contenu vide sur l'écran de l'utilisateur.
  • Rendu des composants. Lorsque tes composants récupèrent des données depuis une API, Suspense met le rendu du composant en pause jusqu’à ce que les données soient disponibles. Cela évite les pages partiellement chargées et contribue à offrir une meilleure expérience aux utilisateurs.
  • Fractionnement de code. Suspense fonctionne avec des fonctionnalités telles que l'React.lazy pour permettre le fractionnement de code et améliorer les performances en ne chargeant les composants que lorsqu'ils sont nécessaires.

Mais React Suspense présente certaines limites dont il faut tenir compte lorsque tu fais évoluer ton application :

  • Prise en charge incomplète de la récupération de données côté serveur. Suspense facilite le chargement des données côté client, mais ne prend pas en charge la récupération de données côté serveur. Pour gérer la récupération de données côté serveur, tu dois utiliser des outils tels que React Query. Par exemple, avec Suspense, tu dois toujours gérer des tâches comme la mise en cache côté serveur et effectuer des requêtes API côté client pour récupérer les données, ce qui peut ajouter de la complexité au SSR.
  • Complexité accrue avec les composants imbriqués. Travailler avec Suspense dans des composants imbriqués peut parfois s’avérer assez complexe. Par exemple, lorsque tu développes une page produit qui affiche des avis, des recommandations et des informations sur les stocks, la coordination entre le chargement des données pour ces composants imbriqués et les limites de Suspense peut entraîner des temps de chargement plus longs. Cela peut compliquer le code, car les dépendances de données et les états de chargement de chaque composant doivent être gérés.
  • Surcoût lié au code standard. Suspense nécessite souvent du code supplémentaire pour gérer les états de chargement, les erreurs et les solutions de secours. Par exemple, dans une grande application, tu pourrais finir par encapsuler de nombreux composants dans des `Suspense` et des `ErrorBoundary`, ce qui ajoute du code répétitif et rend plus difficile le maintien de la cohérence et de la maintenabilité à mesure que ton application se développe.

Rendu côté serveur

En ce qui concerne le SSR, les composants React sont rendus sur le serveur, puis le code HTML entièrement généré est envoyé au client pour être affiché. En revanche, avec le RSC, les composants individuels sont rendus dès qu’ils sont prêts, au lieu d’attendre que l’application entière se charge, comme c’est le cas avec le SSR. Cette approche présente plusieurs avantages :

  • Amélioration des temps de chargement initiaux. En pré-renduant le code HTML sur le serveur, tu permets au navigateur d’afficher le contenu beaucoup plus rapidement. Par exemple, si tu développes un site e-commerce, les utilisateurs peuvent voir les détails des produits immédiatement tandis que le reste de ton JavaScript se charge en arrière-plan. Cela rend ton application plus rapide, surtout si les utilisateurs ont une connexion ou un appareil lent.
  • Avantages en matière de référencement (SEO). Les moteurs de recherche peuvent facilement indexer le code HTML rendu de ton site web, ce qui améliore sa visibilité dans les résultats de recherche. Par exemple, si tu as un blog ou un site web riche en contenu, l'utilisation du SSR permet de garantir que les moteurs de recherche accèdent rapidement à tes articles et les évaluent sans attendre le chargement du JavaScript. Dans ce cas, le SSR te permet d'obtenir un meilleur classement SEO.

Le SSR présente également des limites à prendre en compte :

  • Surcharge d'hydratation. Une fois que le serveur a envoyé le code HTML initial, le navigateur doit l'« hydrater » en y attachant des écouteurs d'événements et en rendant la page interactive. Cela peut entraîner des problèmes de performances, car le navigateur doit afficher la page deux fois : une fois pour le contenu statique et une autre pour les parties interactives. Par exemple, si les applications comportent des fonctionnalités telles que des tableaux de bord analytiques avec des graphiques et des champs de saisie, ce double affichage des différents composants peut entraîner des retards pour les utilisateurs.
  • Charges utiles plus importantes. Avec le SSR, tu dois envoyer l’intégralité du bundle JavaScript au client, ce qui peut augmenter la taille de la charge utile. Par exemple, lorsque tu développes une application volumineuse dotée de multiples fonctionnalités, la quantité de JavaScript envoyée au navigateur peut augmenter considérablement, ce qui peut ralentir les temps de chargement des pages, en particulier sur des connexions plus lentes.
  • Consommation importante de ressources. Le SSR doit générer du code HTML pour chaque requête qui lui est adressée, ce qui entraîne des exigences de traitement accrues et des coûts de serveur plus élevés. Par exemple, si ton application fait face à un pic de trafic, tu devras peut-être augmenter les ressources serveur, ce qui ajoute de la complexité et des coûts à la gestion de l’infrastructure.

Composants serveur React

Les RSC sont un nouveau type de composants dans React qui fonctionnent côté serveur, contrairement aux composants traditionnels, qui fonctionnent côté client. Ils aident à résoudre les problèmes liés à Suspense et au SSR classique en permettant aux composants d’être traités et diffusés sous forme de HTML du serveur vers le client. Les RSC gèrent également la récupération des données sur le serveur, garantissant ainsi que les informations confidentielles, telles que les clés API, ne soient pas divulguées au client.

Les RSC offrent des avantages significatifs :

  • Performances optimisées. Avec les RSC, tu transfères le travail de rendu vers le serveur, ce qui réduit la quantité de JavaScript que les navigateurs de tes utilisateurs doivent exécuter. Par exemple, si tu développes un blog, le contenu HTML peut être diffusé directement, ce qui permet aux articles d'apparaître presque immédiatement sans attendre le traitement JavaScript.
  • Récupération sécurisée des données. Les RSC récupèrent les données côté serveur, améliorant ainsi à la fois la vitesse et la sécurité. Par exemple, dans une application de commerce électronique, le serveur récupère les données sur les produits, en gardant les clés API cachées du client.
  • Réduction de l'exécution de JavaScript côté client. Le transfert du rendu vers le serveur réduit l'exécution de JavaScript sur les appareils des utilisateurs, ce qui améliore les performances, en particulier sur les appareils plus lents. Dans un tableau de bord, par exemple, le serveur traite les composants riches en données, de sorte que le client n'a besoin que d'un minimum de JavaScript.
  • Chargement initial des pages plus rapide. Comme les RSC diffusent du HTML pré-rendu, le contenu se charge rapidement pour les utilisateurs. Sur un site d'actualités, les articles et les images s'affichent instantanément, ce qui évite les écrans blancs pendant le chargement du JavaScript.

RSC vs composants React traditionnels

Par rapport aux composants côté client, les RSC gèrent l'exécution, la gestion des données et les performances de manière différente.

Les composants traditionnels s’exécutent dans le navigateur (côté client), où JavaScript est nécessaire pour afficher l’interface utilisateur (UI). Les RSC s’exécutent sur le serveur en envoyant du HTML pré-rendu à l’appareil client au lieu de tout traiter localement. Cette approche réduit la charge de travail sur l’appareil de l’utilisateur et améliore la vitesse de chargement. La gestion des mises en page et du contenu statique côté serveur est également idéale pour les composants non interactifs ou basés sur des données. Les composants client peuvent être imbriqués dans des RSC là où l'interactivité est nécessaire, comme pour les boutons ou les formulaires, tout en conservant les données sensibles en sécurité sur le serveur.

Les composants traditionnels peuvent augmenter la taille du bundle JavaScript côté client, ce qui peut ralentir les performances de l'application. Les RSC n'augmentent pas la taille du package client puisqu'ils fonctionnent côté serveur, ce qui réduit les téléchargements et accélère le chargement des pages. Tu peux aussi utiliser les RSC pour améliorer la mise en cache. Le contenu rendu par le serveur est plus facile à mettre en cache, ce qui accélère les réponses pour les données fréquemment consultées, comme les produits populaires d'une boutique en ligne, sans avoir à interroger la base de données à plusieurs reprises.

Comment mettre en œuvre les RSC

Pour implémenter les RSC dans ton projet, suis ces étapes pour configurer ton environnement et commencer à utiliser efficacement les composants côté serveur et côté client.

Configuration du projet

Tout d'abord, assure-toi que la dernière version de Node.js est installée sur ta machine. La première étape consiste à créer un nouveau projet React depuis ton shell ou ton terminal :

npx create-react-app your-app --template cra-template-pwa
cd your-app

Une fois ton projet initialisé, installe les dépendances requises pour les RSC :

npm install react@18 react-dom@18 babel-loader@8 @babel/preset-react webpack@5 webpack-cli


Pour plus d'informations, tu peux consulter la documentation officielle relative à chacune de ces bibliothèques : React, react-dom, webpack, Babel et webpack-cli.

Exécute la commande suivante pour installer les chargeurs pour les fichiers CSS et les fichiers de ressources tels que les SVG, ce qui permettra à ton application de traiter et d'inclure des feuilles de style et des fichiers multimédias :

npm install css-loader style-loader file-loader --save-dev

Configure Babel en créant un fichier .babelrc fichier à la racine de ton projet avec le contenu suivant :

{
 "presets": ["@babel/preset-react"]
}

Crée un nouveau fichier nommé webpack.config.js dans le répertoire racine de ton projet et ajoute la configuration suivante pour configurer webpack :

const path = require("path");
module.exports = [
 // Server-side configuration
 {
   entry: "./src/server.js", // Server entry point
   target: "node",
   output: {
     path: path.resolve(__dirname, "dist"),
     filename: "server.js",
   },
   module: {
     rules: [
       {
         test: /\.jsx?$/,
         use: "babel-loader",
         exclude: /node_modules/,
       },
       {
         test: /\.css$/, // Rule for CSS files
         use: ["style-loader", "css-loader"],
       },
       {
         test: /\.(png|jpe?g|gif|svg)$/, // Rule for image files
         use: ["file-loader"],
       },
     ],
   },
   resolve: {
     extensions: [".js", ".jsx"],
   },
 },
 // Client-side configuration
 {
   entry: "./src/index.js", // Client entry point
   target: "web", // This tells Webpack to bundle for the browser
   output: {
     path: path.resolve(__dirname, "dist"),
     filename: "client.js", // Client-side bundle
   },
   module: {
     rules: [
       {
         test: /\.jsx?$/,
         use: "babel-loader",
         exclude: /node_modules/,
       },
       {
         test: /\.css$/, // Rule for CSS files
         use: ["style-loader", "css-loader"],
       },
       {
         test: /\.(png|jpe?g|gif|svg)$/, // Rule for image files
         use: ["file-loader"],
       },
     ],
   },
   resolve: {
     extensions: [".js", ".jsx"],
   },
 },
];

Création de tes composants

Une fois webpack configuré, tu peux maintenant créer un fichier nommé server.js à l'intérieur du dossier src avec le code suivant pour configurer le point d'entrée de ton serveur :

import React from "react";
const express = require("express");
const ReactDOMServer = require("react-dom/server");
const App = require("./App").default;


const app = express();


// Serve the static files from the 'dist' folder (where Webpack will put client.js)
app.use(express.static("dist"));


app.get("*", (req, res) => {
  const appHtml = ReactDOMServer.renderToString(<App />);


  res.send(`
    <!DOCTYPE html>
    <html lang="en">
      <head><title>React Server Components</title></head>
      <body>
        <div id="root">${appHtml}</div>
        <!-- Include the client-side bundle -->
        <script src="/client.js"></script>
      </body>
    </html>
  `);
});


app.listen(3000, () => console.log("Server running on port 3000"));

Dans le dossier src, crée un nouveau fichier appelé UserList.server.js pour configurer un composant serveur de base qui récupère des données :

import React from "react";


function UserList() {
  // Dummy array of users
  const users = [
    { id: 1, name: "John Doe" },
    { id: 2, name: "Jane Smith" },
    { id: 3, name: "Alice Johnson" },
  ];


  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}


export default UserList;

Ce composant affiche les données utilisateur et renvoie une liste HTML. Pour ajouter de l'interactivité côté client, crée un fichier nommé Counter.client.js dans le répertoire src pour ton composant client :

import React, { useState } from "react";


function Counter({ initialCount }) {
  const [count, setCount] = useState(initialCount);


  return (
    <div>
      <button
        onClick={() => {
          setCount((prevCount) => {
            const newCount = prevCount + 1;
            return newCount;
          });
        }}
      >
        Increment 1
      </button>
      <p>Count: {count}</p>
    </div>
  );
}


export default Counter;

De cette façon, le serveur initialise l'état et le client gère l'interactivité. Tu as maintenant configuré un processus complet pour les RSC, créé un composant serveur, transmis des données à un composant client et activé l'interactivité côté client.

Ensuite, mets à jour src/App.js pour y inclure le code suivant, qui intègre à la fois les composants serveur et client :

import React from "react";
import UserList from "./UserList.server";
import Counter from "./Counter.client";


function App() {
  return (
    <div>
      <h1>Users</h1>
      <UserList />
      <Counter initialCount={50} />
    </div>
  );
}


export default App;

Exécute et teste le code

Désormais, lorsque le serveur rend le composant App, il rendra également l'Dashboard UserList en tant que composant serveur et enverra le code HTML au client.

Pour exécuter ton serveur, compile le code et lance-le :

npx webpack
node dist/server.js

L'exécution de ces commandes renverra Server running on port 3000. À ce stade, ton application affiche des composants React à la fois sur le client et sur le serveur !

Bonnes pratiques pour l'utilisation des RSC

Comme les RSC gèrent la majeure partie du rendu côté serveur, transférer autant que possible le rendu de ton application vers le serveur peut améliorer considérablement les performances tout en conservant les fonctionnalités interactives là où c’est nécessaire. Voici quelques bonnes pratiques qui peuvent t’aider à y parvenir et à améliorer la vitesse, la flexibilité et la facilité de gestion de ton application grâce aux RSC.

Tout d'abord, utilise les RSC pour récupérer des données depuis des API ou des bases de données. Si tu as déjà récupéré des données sur le serveur, ne les récupère pas à nouveau côté client. Par exemple, si tu charges des données utilisateur sur le serveur et que tu les transmets au client, il n'est pas nécessaire d'effectuer un deuxième appel API côté client, sauf si les données changent.

Décomposer le code en petits morceaux et charger de manière sélective les scripts nécessaires à l’aide d’outils tels que Vite ou webpack peut aider à améliorer les temps de chargement. Crée des composants réutilisables dans toute ton application. Par exemple, si plusieurs pages doivent afficher une liste d’utilisateurs, crée un composant « UserList » qui fonctionne partout.

Enfin, veille à ce que les composants serveur restent légers en les concentrant uniquement sur le rendu des données, car ils n’ont pas besoin de gérer l’état comme le font les composants client. Concentre-toi sur leur légèreté et sur leur rôle exclusif de rendu des données. N’hydrate que les parties d’une page qui doivent être interactives. Par exemple, si la page est principalement statique mais comporte un formulaire ou un bouton interactif, n’hydrate que ces composants.

Défis et limites des RSC

Bien que les RSC présentent des avantages, il est également important de comprendre les obstacles et les limites liés à leur intégration dans ton projet.

Gestion de l'état

Les composants serveur ne peuvent pas interagir avec les méthodes de cycle de vie telles que `useEffect` ou `useState`. Cela signifie que tu ne peux pas gérer l'interactivité côté client au sein des composants serveur. Par exemple, si un formulaire est rendu côté serveur, tu auras besoin d'un composant client pour gérer les modifications de saisie en temps réel.

Lorsque tu utilises à la fois des composants côté client et côté serveur dans tes projets, il est important de gérer l’interaction entre ces deux types de composants dans toute ton application pour éviter tout problème. Par exemple, si ton application récupère des données depuis le serveur et permet aux utilisateurs de modifier ces données localement sur leurs appareils, tu pourrais rencontrer des problèmes pour maintenir la cohérence des données entre le serveur et les composants côté client.

Code non sérialisable

Les composants côté serveur ne peuvent utiliser que des props sérialisables, ce qui signifie que tu ne peux pas passer de fonctions, de symboles ou d'objets complexes qui ne peuvent pas être sérialisés. Par exemple, envoyer une fonction de rappel d'un composant côté serveur vers un composant client entraînera un message d'erreur. Les composants côté serveur n'ont pas accès aux API du navigateur telles que window, document ou localStorage. Si tu as besoin d'interagir avec le DOM, cela doit se faire dans un composant client.

Incohérences d'hydratation

Si le code HTML affiché par le serveur ne correspond pas à ce qu'attend le JavaScript côté client, cela peut entraîner des problèmes pendant le processus d'hydratation. Par exemple, des différences dans le formatage des dates entre le serveur et le client peuvent causer de subtils décalages. Les décalages d'hydratation peuvent être difficiles à déboguer car la cause profonde n'est pas toujours évidente.

Compatibilité avec les bibliothèques tierces

Certaines bibliothèques tierces peuvent ne pas fonctionner correctement avec les RSC, en particulier celles qui dépendent fortement des techniques de rendu côté client ou des API spécifiques aux navigateurs. Par exemple, des bibliothèques telles qu’react-router-dom nécessitent un rendu côté client. Tu devras peut-être remplacer ou adapter certaines bibliothèques pour qu’elles fonctionnent avec les RSC.

Solutions aux problèmes courants liés aux RSC

Il existe des solutions pratiques que tu peux mettre en œuvre pour maintenir la cohérence et résoudre les problèmes courants liés aux RSC.

Utilise une gestion cohérente de l'état

Utilise des outils de gestion d'état qui fonctionnent à la fois sur le serveur et le client, comme Redux ou Zustand. Ces bibliothèques te permettent de centraliser ton état afin que les composants rendus par le serveur et ceux côté client puissent accéder aux mêmes données. Par exemple, tu pourrais utiliser Redux pour stocker un état global accessible aux deux côtés de l'application.

Assure-toi de maintenir un flux de données entre le serveur et le client en partageant le contexte. Par exemple, lorsque tu transfères des données utilisateur entre les composants serveur et client, assure-toi que les informations sont gérées de manière centralisée pour éviter toute divergence.

Utilise du code non sérialisable et refactorise les composants

Envisage d'utiliser des outils de développement ou des linters de code pour identifier les propriétés non sérialisables susceptibles de causer des problèmes avec les RSC. Par exemple, des outils tels qu'ESLint peuvent être configurés pour détecter les props de fonction transmises depuis des composants côté serveur.

Veille à refactoriser les composants pour t'assurer que les props peuvent être sérialisées et éviter tout problème avec le SSR. Une façon de procéder consiste à déplacer certaines opérations, comme les gestionnaires d'événements, vers les composants client. Par exemple, lorsque tu transmets une fonction de rappel depuis un composant serveur, assure-toi que le code est adapté pour que l'opération se déroule au sein du composant client où elle est utilisée.

Gérer les incohérences d'hydratation

Pour résoudre les incohérences d'hydratation, il faut recourir à des techniques de test et de débogage proactives :

  • Mode strict. Active le mode strict de React pour détecter les problèmes pendant le processus de développement. Le mode strict signalera les erreurs au fur et à mesure que tu travailles, ce qui te permettra de les corriger avant qu’elles ne deviennent des problèmes dans le produit final.
  • Tests approfondis. Assure-toi que des plans de test approfondis sont en place pour détecter tout problème lié à l'hydratation. L'automatisation des tests peut imiter les processus de rendu côté serveur et côté client pour garantir l'uniformité. Envisage d'utiliser des outils tels que Cypress ou Jest pour vérifier que le résultat affiché est cohérent dans les environnements serveur et client.

Assure-toi de la compatibilité des bibliothèques tierces

Si un logiciel tiers ne fonctionne pas avec les composants serveur comme l’exigent les exigences de ton projet, explore d’autres options compatibles avec le serveur. Si tu utilises une bibliothèque open source pour ton projet, tu pourrais envisager de contribuer à son développement pour y inclure la prise en charge des RSC. En contribuant, tu peux améliorer ta propre application et avoir un impact positif sur la communauté au sens large qui s’appuie sur cette même bibliothèque pour son travail.

En relevant ces défis avec des stratégies adaptées, tu peux contourner efficacement les limites des RSC et créer des applications robustes et performantes.

Conclusion

Dans cet article, nous avons expliqué les techniques de rendu de React. Nous avons présenté React Suspense et le SSR, et fourni un guide plus approfondi sur les RSC. Tu peux utiliser les RSC pour améliorer les performances de ton application en réduisant le besoin de traitement JavaScript côté client et en accélérant le chargement initial des pages.

Si tu souhaites tester les RSC dans tes projets, la première étape consiste à identifier les composants de ton application qui pourraient tirer parti du SSR. Tu pourras ensuite intégrer progressivement les RSC dans ton code.

La gestion de l'infrastructure pour le SSR et les composants serveur peut s'avérer complexe. L'utilisation d'Upsun, une plateforme en tant que service (PaaS), simplifie le déploiement et la mise à l'échelle de tes applications React. Grâce à sa prise en charge intégrée de Node.js et à sa scalabilité automatique, Upsun peut t'aider à gérer les pics de trafic en toute fluidité. Il fournit également des outils de surveillance et de sécurité et te permet de gérer plusieurs applications ou microservices dans différents langages au sein d'un même projet. Ainsi, tu peux te concentrer sur le développement de ton application React tandis qu'Upsun gère l'infrastructure de base.

Restez informé

Abonnez-vous à notre newsletter mensuelle pour les dernières mises à jour et nouvelles.

Votre meilleur travail
est à l'horizon

Essai gratuit