devsite/docs-site-interne/10-plan-server-components.md
2026-04-28 14:10:05 +02:00

7.4 KiB
Raw Permalink Blame History

Plan — migration vers Server Components (données Strapi)

Dernière mise à jour : 2026-04-28
Statut : document de planification — aucun changement de code appliqué dans ce lot ; mise en œuvre quand vous le déciderez.

Prérequis lu : vous restez en npm run dev (Turbopack) pour le moment ; ce document décrit aussi ce que donne next build / next start en complément.


1. Objectif

Réduire le pattern actuel: pages marquées "use client" qui appellent fetch() dans useEffect après hydration.

Vers: async page (ou composant serveur parent) qui appelle fetch côté serveur Next, avec mise en cache/revalidation possible, puis rendu HTML déjà rempli de contenu texte + balises images.


2. État actuel (référence doc + code)

Page / zone Fichier Pattern actuel
Accueil app/page.tsx "use client" + useEffectgetHomepageData()
Liste portfolio app/portfolio/page.jsx idem → /api/projects
Liste compétences app/competences/page.jsx idem → /api/competences
Compétence (vignettes réalisations) app/competences/[slug]/page.tsx idem, fetchs multiples

Conséquences documentées dans 09-performances-images.md §3.4 : premier paint sans données, pas de data cache Next sur ces flux, images découvertes tard.


3. Ce que « Server Components » implique (concrètement)

3.1 Principe

  • Un Server Component est un composant sans "use client" qui peut être async et utiliser await fetch(...) directement dans le corps du composant.
  • Le rendu sexécute sur le serveur Node (processus Next), une fois par requête (sauf cache), pas dans le navigateur.

3.2 Ce qui reste obligatoirement en Client Components

Tout ce qui utilise des hooks React hors contexte « serveur » limité : useState, useEffect, useRef pour le menu mobile, événements clavier (Escape), Swiper, portal pour modales, localStorage, etc.

Stratégie classique : fichier page sans "use client" (serveur), qui await les données puis rend:

<>
  <PageHeader … />           // peut être serveur
  <ListeClientOuMixte … />    // sous-arbre `"use client"` uniquement où nécessaire
</>

Les carousels (Carousel, VignetteCarousel) restent très probablement en clients tant quils dépendent de Swiper avec effets hydratés — on leur passe en props les URLs / textes déjà résolus côté serveur.

3.3 Layout root (app/layout.tsx)

Aujourdhui: "use client" (+ menu burger, état drawer, etc.). Option A : garder le layout tel quel et ne migrer que les pages feuilles — Next autorise une page serveur même si le layout parent est client (limites: enfants peuvent être serveur sous certaines compositions ; selon Next 1315 il faut vérifier quaucune contrainte n« impose » tout client — en pratique souvent extraction ServerLayout léger OU layouts par segment /portfolio/layout.tsx serveur). Option B (plus tard) : scinder en layout serveur + header/footer client importés dynamiquement ou composants clients enfants.

Cest le point le plus structurant ; il sera arbitré au moment de limplémentation (lot par lot).

3.4 Appels Strapi : URL

  • Côté serveur Next, getApiUrl() sans window utilise NEXT_PUBLIC_API_URL (ou défaut prod). Pour le dev sur la même machine, sassurer que cette env pointe soit vers http://localhost:1337, soit vers lURL publique si IIS/Strapi le servent aussi — sinon risque que le SSR appelle https://api.fernand… depuis le serveur sans route réseau correcte (variable denv par environnement recommandée).
  • Harmoniser avec rewrites existants /api/* → Strapi: possibilité dutiliser fetch(new URL('/api/...', request.url ?? base)) en SSR si vous préférez passer par Next (même origin).

3.5 fetch et cache

  • fetch(url, { next: { revalidate: 60 } }): ISR-like, données rafraîchies au plus toutes les 60 secondes selon docs Next 15 (cache par défaut a évolué — à relire next doc au moment du codage).
  • Pour du toujours frais en dev, cache: 'no-store' peut rester le comportement désiré jusquà validation.

3.6 Mode dev (Turbopack)

  • Les Server Components fonctionnent en next dev ; le cache fetch est moins représentatif de la prod quavec next start.
  • Le gain perçu (HTML complet, moins de waterfall client) reste visible en dev sur le réseau / Elements (contenu dans le HTML source).

4. Gains réels attendus

Dimension Avant (client fetch) Après (données en serveur)
Premier contenu Spinner / squelette jusquà fin de fetch + JSON parse côté client Texte + structure + images (next/image avec src déjà dans le HTML) plus tôt
Waterfall HTML minimal → chargement JS → useEffect → fetch → re-render Un aller-retour serveur Strapi lors du SSR Next (possible parallélisation Promise.all)
Cache Next Aucun data cache pour ces pages Possibilité revalidate / tags plus tard
SEO / réseaux lents Contenu peu présent sans exécuter JS Contenu lisible avec HTML seul (meilleur pour indexation ; utile même si votre besoin SEO est modeste)
Lighthouse LCP Portrait / hero souvent retardé par la chaîne client Déjà dans le flux initial SSR (souvent gain LCP mesurable après stabilisation)

Limite honnête : next dev conserve un JS volumeux (Turbopack, pas minifié comme prod). Le gain bundle sera maximum après next build + next start (ou équivalent).


5. Ordre de migration proposé (par risque croissant)

  1. /portfolio (liste seule — une liste, pattern clair).
  2. /competences (liste identique).
  3. / (home — getHomepageData + retry ; extraire logique fetch dans lib/ serveur).
  4. /competences/[slug] (deux modes : vignettes réalisations vs redirect vers container compétences — attention aux branches).

Ensuite: fiches détail ContentSection / fetchData peuvent suivre une feuille de route analogue (nombreuses pages déjà partiellement factorisées via fetchData).

À chaque étape: tests manuels des routes, erreurs réseau Strapi, images encore correctes (pickStrapiImage inchangé côté props).


6. Hors scope immédiat (rappels)

  • Ne pas renommer tous les fichiers .jsx.tsx en même temps sans besoin ; migrer fichier par fichier.
  • Ne pas activer compress: true côté Next tant que derrière ARR/IIS le tunnel reste incompatible (voir 09-performances-images.md §4.6).
  • Évaluation next build : à planifier après stabilisation SSR en dev ou sur une branche.

7. Liens internes