Composants du serveur React : l'architecture du Zero-Bundle
Des cascades « useEffect » à « async/await ». Une plongée technique approfondie dans RSC, Next.js App Router, Server Actions et la hiérarchie de mise en cache.
Pendant 10 ans, l’écosystème React a dérivé vers le « Client-Side Everything ».
Nous avons construit d’énormes applications à page unique (SPA).
Nous avons récupéré les données dans useEffect.
Nous avons montré 10 fileuses pendant que les cascades se résolvaient.
Et nous avons envoyé 500 Ko de JavaScript à un utilisateur utilisant une connexion 3G au Brésil, se demandant pourquoi la « conversion » était faible.
React Server Components (RSC) est la correction. Ce n’est pas seulement une fonctionnalité. Il s’agit d’un changement architectural fondamental qui ramène le centre de gravité là où il doit être : le Datacenter.
Chez Maison Code Paris, nous avons migré des plateformes e-commerce massives vers Next.js App Router. Le résultat ? 40 % de JavaScript en moins, Largest Contentful Paint (LCP) 2 fois plus rapide et une expérience de développement qui ressemble à de la triche.
Pourquoi Maison Code en parle
Chez Maison Code Paris, nous agissons comme la conscience architecturale de nos clients. Nous héritons souvent de stacks “modernes” construites sans compréhension fondamentale de l’échelle.
Nous abordons ce sujet car il représente un point de pivot critique dans la maturité de l’ingénierie. Une mise en œuvre correcte différencie un MVP fragile d’une plateforme résiliente de niveau entreprise.
Pourquoi Maison Code parie sur RSC
Nous ne recherchons pas chaque nouveau framework. Nous recherchons le LTV client. RSC est la première architecture qui aligne les performances techniques avec les objectifs métier :
- SEO : diffusion HTML parfaite pour les robots d’exploration (Google Bot adore RSC).
- Conversion : interactions « Ajouter au panier » plus rapides via l’interface utilisateur optimiste.
- Durabilité : réduisez la consommation de batterie des appareils des utilisateurs en déchargeant les calculs vers le cloud. Nous formons toutes nos agences partenaires sur cette stack car c’est l’avenir du Commerce Haute Performance.
Le modèle mental : le serveur comme arbre de composants
Dans l’ancien monde (Pages Directory ou Create-React-App), le serveur envoyait du HTML et les fonctionnalités clés du client “hydratées”. Dans le monde RSC, React s’exécute sur le serveur.
Lorsqu’un utilisateur demande /product/123 :
- Le serveur affiche « ProductPage ».
- Il exécute
await db.query(). - Il résout les données.
- Il sérialise le résultat dans un format spécial (Flight Protocol).
- Il diffuse ceci sur le navigateur.
- Le navigateur affiche l’interface utilisateur.
Surtout : Le code du composant serveur ne quitte jamais le serveur. Si vous importez « moment.js » (200 Ko) dans un composant serveur pour formater une date, l’utilisateur en télécharge 0 Ko. Ils voient simplement le texte « 23 novembre 2025 ».
Récupération de données : mort de useEffect
L’ère des « Loading Spinners » provoqués par la logique côté client est révolue. Nous ne créons plus de routes API uniquement pour alimenter notre propre frontend.
L’ancien modèle (Client FetcH) :
// Composant client
fonction Produit() {
const [données, setData] = useState(null);
utiliserEffet(() => {
fetch('/api/product').then(res => res.json()).then(setData);
}, []);
si (!data) renvoie <Spinner /> ;
return <div>{data.name}</div> ;
}
Le nouveau modèle (RSC) :
// Composant serveur
importer { db } depuis '@/lib/db' ;
exporter la fonction asynchrone par défaut ProductPage() {
// Accès direct à la base de données. Sécurisé. Rapide.
const data = attendre db.product.findFirst();
return <div>{data.name}</div> ;
}
Cela fonctionne sur le backend. Ce sont les données qui attendent l’utilisateur, et non l’inverse.
Interactivité : la directive “Utiliser le client”
Mais le HTML statique est ennuyeux. Nous avons besoin de boutons « Ajouter au panier ». Nous réintroduisons l’interactivité à l’aide des Composants Client. Vous marquez un fichier avec « utiliser le client ». Cela indique à Next.js : “Incluez ce fichier dans le bundle JavaScript.”
Modèle de composition : La stratégie « Dot ». Ne faites pas de la page entière un composant client. Créez les feuilles des composants clients.
// Composant serveur (mise en page)
exporter la fonction asynchrone par défaut Page() {
const produit = attendre db.product.findFirst();
retour (
<div>
<h1>{product.title}</h1> {/* Taille de paquet nulle */}
<PriceDisplay value={product.price} /> {/* Taille du paquet nulle */}
<AddToCartButton id={product.id} /> {/* Composant client (interactif) */}
</div>
);
}
Actions du serveur : mutations de type sécurisé
Comment soumettons-nous les formulaires ? « Routes API » ? “Axios” ? « REPOS » ? Non. Actions du serveur. Nous écrivons une fonction qui s’exécute sur le serveur et la transmettons comme accessoire au formulaire.
// actions.ts
'utiliser le serveur'
fonction d'exportation asynchrone addToCart (formData : FormData) {
const productId = formData.get('productId');
wait db.cart.create({ productId });
// Demande au cache local de se mettre à jour
revalidatePath('/cart');
}
// Bouton.tsx
importer { addToCart } depuis './actions' ;
fonction d'exportation AddToCartButton() {
retour (
<form action={addToCart}>
<button type="submit">Ajouter</button>
</form>
)
}
Cela fonctionne sans JavaScript activé (amélioration progressive). Si JS se charge, Next.js intercepte la soumission et effectue effectivement un appel API. Mais c’est comme appeler une fonction.
UI optimiste : useOptimistic
Lorsque l’utilisateur clique sur “Ajouter”, nous souhaitons un retour instantané. Nous ne voulons pas attendre l’aller-retour du serveur. RSC introduit « useOptimistic ».
'utiliser le client'
importer { useOptimistic } depuis 'react' ;
fonction d'exportation LikeButton({ likeCount, action }) {
const [optimisticLikes, addOptimisticLike] = useOptimistic(
commeCount,
(état, newLike) => état + 1
);
retour (
<bouton onClick={async () => {
addOptimisticLike(1); // Mise à jour immédiate de l'interface utilisateur
attendre une action(); // Synchronisation en arrière-plan du serveur
}}>
J'aime : {optimisticLikes}
</bouton>
);
}
La hiérarchie de mise en cache
Next.js implémente une mise en cache agressive pour rendre les RSC rapides. Comprendre cette hiérarchie est la partie la plus difficile de la courbe d’apprentissage.
- Demander la mémorisation : si vous appelez
getUser()dans la mise en page etgetUser()dans la page, Next.js le dédupe. Il ne s’exécute qu’une seule fois par requête. - Cache de données : le résultat de « fetch » est stocké sur le disque du serveur. Il persiste à travers les demandes.
fetch('...', { suivant : { tags : ['produits'] } }) - Cache de route complet : la charge utile HTML + Flight rendue est mise en cache au moment de la construction (génération de site statique).
- Cache du routeur : Le navigateur met en cache les pages visitées en mémoire pendant 30 s pour une navigation avant/arrière instantanée.
Invalidation :
Lorsque vous mettez à jour un produit, vous devez appeler revalidateTag('products') dans votre action serveur. Cela purge instantanément les couches 2 et 3.
10. Prérendu partiel (PPR)
Le statique (SSG) est rapide mais obsolète. Dynamic (SSR) est frais mais lent. Next.js 14 a introduit PPR. Il s’agit du modèle « Hole in the Donut ». Le Shell (en-tête, pied de page, barre latérale) est pré-rendu au moment de la construction. Le « Prix du produit » est le trou. Il se charge dynamiquement. L’utilisateur obtient du HTML instantané (The Shell) et le flux de pièces dynamiques 100 ms plus tard. Cela évite l’apparition de « l’écran blanc de la mort » lors des requêtes dans la base de données.
11. Limites du streaming et du suspense
RSC divise la page en morceaux.
return <Suspense fallback={<Squelette />}><SlowComponent /></Suspense>
Le serveur envoie l’en-tête HTTP Transfer-Encoding: chunked.
- Morceau 1 :
<html>...<nav>... <Squelette> - (DB termine)
- Morceau 2 :
<script>replace(Skeleton, RealContent)</script>Ce Time To First Byte (TTFB) est essentiel pour le référencement et les performances perçues.
13. RSC vs Architecture insulaire (Astro)
Astro a popularisé les “Îles” (HTML statique + petits trous d’interactivité). RSC est similaire mais différent.
- Astro : Expédiez 0 JS par défaut. Hydratez explicitement
<Counter client:load />. - RSC : Expédiez 0 JS par défaut. Hydratez les composants marqués « utiliser le client ». La différence réside dans le Routeur. Next.js dispose d’un routeur côté client (sensation SPA). Astro utilise la navigation multipage (sensation classique). Pour le commerce électronique (où conserver l’état du panier lors du chargement des pages est vital), le modèle Next.js/RSC est généralement supérieur au modèle MPA pur.
14. La gestion de l’État dans un monde RSC
Où va Redux ? Nulle part. Vous n’en avez pas besoin. Si l’état est « Données du serveur » (Produits, Profil utilisateur), il réside dans le composant serveur (récupéré par requête). Si l’état est « UI State » (Modal Open, Accordion Expanded), il réside dans « useState » à l’intérieur d’une feuille de composant client. Nous utilisons uniquement Global State (Zustand/Context) pour les données client véritablement globales : le Cart et le Auth Token. Tout le reste (90 % des anciens magasins Redux) est supprimé.
15. Conclusion
Les composants React Server constituent le plus grand changement dans le développement frontend depuis l’introduction d’AJAX. Ils nous permettent de créer des « MPA (Multi-Page Apps) avec l’âme des SPA ». Nous obtenons le référencement, les performances et la simplicité du rendu du serveur. Nous obtenons la riche interactivité de React.
Pour le commerce électronique à grande échelle, où chaque milliseconde de latence est liée aux revenus, RSC est la seule architecture viable pour les 5 prochaines années.
Vous migrez vers Next.js ?
Êtes-vous bloqué sur une application Create-React lente ?
Architectez votre migration avec RSC. Engagez nos Architectes.