Aller au contenu
Logo
ReactServer ComponentsNext.jsPerformanceArchitecture

React Server Components en production : ce que j'ai appris

5 min de lecture

Les Server Components promettent moins de JavaScript côté client et de meilleures performances. Après plusieurs projets en production, voici ce qui fonctionne, et les pièges à éviter.

Les React Server Components existent depuis React 18 et sont devenus le modèle par défaut dans Next.js App Router. Deux ans après leur introduction, j'ai suffisamment de recul pour en parler sans répéter la documentation officielle. Ce qui suit vient de vrais projets, pas de tutoriels.

Le principe en 30 secondes

Un Server Component s'exécute uniquement sur le serveur. Il peut accéder directement à la base de données, lire des fichiers, appeler des APIs internes, le tout sans envoyer le code correspondant au navigateur. Le bundle JavaScript côté client est plus léger. La page se charge plus vite. L'utilisateur voit le contenu plus tôt.

C'est la théorie. En pratique, c'est plus nuancé.

Là où ça brille vraiment

Les pages à contenu dynamique. Pages de blog, fiches produit, dashboards de consultation : tout ce qui affiche des données sans interaction complexe. Les Server Components excellent ici parce que les données sont récupérées côté serveur, le HTML est généré, et le client reçoit une page prête à l'emploi sans avoir besoin de télécharger et exécuter tout le JavaScript qui aurait été nécessaire pour faire la même chose côté client.

Les chiffres parlent d'eux-mêmes. Sur un projet e-commerce, le passage aux RSC a réduit le bundle JavaScript de la page produit de 40%. Le Largest Contentful Paint est passé sous la barre des 1,5 secondes. Pas sur un benchmark de labo. En production, avec de vrais utilisateurs, sur des connexions variées.

La cohabitation avec les Client Components fonctionne bien une fois qu'on a compris la logique. Le 'use client' n'est pas un aveu d'échec. C'est un outil. Les formulaires, les modales, les composants interactifs restent des Client Components. Le reste est serveur par défaut. La clé, c'est de pousser le 'use client' le plus bas possible dans l'arbre de composants. Un bouton interactif dans une page n'a pas besoin de rendre toute la page côté client.

Et le data fetching, enfin simplifié. Plus besoin du trio infernal useEffect + useState + loading state pour afficher des données. Un async Server Component qui fait un fetch ou une requête Prisma directement. Le code est plus lisible, plus court, et il y a moins d'endroits où un bug peut se cacher.

// Avant : Client Component avec useEffect
// 25 lignes de boilerplate

// Après : Server Component
async function ProductPage({ id }) {
  const product = await db.product.findUnique({ where: { id } })
  return <ProductDisplay product={product} />
}

Les pièges, parce qu'il y en a

La frontière serveur/client mal placée. C'est l'erreur que je vois le plus souvent, y compris dans mon propre code au début. Mettre 'use client' trop haut dans l'arbre, sur un layout par exemple, et d'un coup tout ce qui est en dessous devient client. Même les composants qui n'ont aucun besoin d'être côté client. La règle est simple : chaque 'use client' doit être justifié par une interaction utilisateur. Un onClick, un onChange, un useState, un useEffect. Si le composant n'a rien de tout ça, il n'a pas besoin d'être client.

La sérialisation des props est un piège récurrent. Les données qui passent d'un Server Component à un Client Component doivent être sérialisables en JSON. Pas de fonctions, pas de classes, pas d'objets Date bruts. C'est logique quand on y réfléchit (les données traversent la frontière réseau), mais c'est un piège classique quand on refactore du code existant qui passait des callbacks partout.

Le cache qui joue des tours. Next.js cache agressivement les résultats des Server Components. Excellent pour les performances, source de bugs subtils quand les données doivent être fraîches. J'ai passé deux heures à chercher pourquoi un dashboard affichait des données d'il y a 15 minutes avant de réaliser que c'était le cache. Maintenant je configure explicitement la stratégie de cache pour chaque route : revalidate avec un intervalle pour le contenu éditorial, no-store pour les données temps réel.

Et les vulnérabilités récentes. Deux CVE ont été publiées sur les RSC (CVE-2025-55184 et CVE-2025-55183), affectant Next.js 13.x à 16.x. Rien de catastrophique, mais un rappel utile que la veille sécurité reste indispensable même sur un framework mature et populaire. Mettez à jour vos dépendances. Pas demain. Cette semaine.

Quand ne pas utiliser les RSC

Les applications temps réel comme le chat ou la collaboration en direct. Les WebSockets et les interactions continues vivent mieux côté client, et essayer de forcer les RSC dans ce contexte ajoute de la complexité sans bénéfice.

Les interfaces très interactives comme les éditeurs de texte riche ou le drag and drop complexe. Le surcoût de la frontière serveur/client ne vaut pas le coup, et vous allez vous retrouver à mettre 'use client' sur tellement de composants que l'intérêt des RSC disparaît.

Les prototypes rapides. Si vous itérez vite et que la performance n'est pas critique, restez en full client. C'est plus simple, il y a moins de concepts à gérer, et vous pourrez toujours migrer vers les RSC plus tard si le projet grandit.

Pour commencer concrètement

Si vous démarrez un projet Next.js aujourd'hui, laissez tout en Server Component par défaut. C'est le comportement natif de l'App Router, vous n'avez rien à faire. Ajoutez 'use client' uniquement quand le navigateur en a besoin, c'est-à-dire quand il y a des interactions, des hooks d'état ou des effets. Mesurez avec les Core Web Vitals, la taille du bundle, le temps de chargement réel. Et ajustez la frontière serveur/client en fonction des résultats, pas en fonction de ce qu'un article de blog (y compris celui-ci) vous dit de faire.

Les RSC ne sont pas une mode. C'est la direction que prend React. Sur mes projets, c'est le modèle par défaut, pas par dogme, mais parce que les résultats en performance et en maintenabilité sont mesurables.

Un projet React/Next.js à optimiser ou à lancer ? Réservez un créneau et on regarde ensemble les bons choix d'architecture pour votre cas.

Partager cet article