React : performance et déploiement
Principes de performance
Section intitulée « Principes de performance »- Mesurer avant d’optimiser (React DevTools Profiler, onglet Performance du navigateur).
- Réduire le travail inutile : état au bon endroit, listes avec
key, pas de calcul lourd dans le rendu. - Charger moins de JavaScript : découpage du code, dépendances raisonnables.
memo, useMemo, useCallback
Section intitulée « memo, useMemo, useCallback »import { memo, useMemo, useCallback, useState } from 'react';
const Ligne = memo(function Ligne({ nom, onSupprimer,}: { nom: string; onSupprimer: (nom: string) => void;}) { return ( <li> {nom} <button onClick={() => onSupprimer(nom)}>×</button> </li> );});
export function Liste({ noms }: { noms: string[] }) { const [filtre, setFiltre] = useState(''); const visibles = useMemo( () => noms.filter((n) => n.includes(filtre)), [noms, filtre], ); const supprimer = useCallback( (nom: string) => console.log('supprimer', nom), [], ); return ( <> <input value={filtre} onChange={(e) => setFiltre(e.target.value)} /> <ul> {visibles.map((n) => ( <Ligne key={n} nom={n} onSupprimer={supprimer} /> ))} </ul> </> );}| Outil | Rôle |
|---|---|
memo(Composant) |
Évite le rendu si les props n’ont pas changé |
useMemo |
Mémorise un résultat de calcul |
useCallback |
Mémorise une fonction (pour des props de composants memo) |
À utiliser là où la mesure montre un gain : ils ajoutent de la complexité. Le compilateur React (React Compiler, installable avec Vite et Babel) automatise cette mémoïsation et réduit ce besoin ; lire sa documentation pour l’activer.
Découpage du code : lazy et Suspense
Section intitulée « Découpage du code : lazy et Suspense »import { lazy, Suspense } from 'react';
const Graphiques = lazy(() => import('./Graphiques'));
export function Tableau() { return ( <Suspense fallback={<p>Chargement du graphique…</p>}> <Graphiques /> </Suspense> );}Avec React Router, charger chaque page à la demande (lazy: () => import('./pages/Client')). Le build de Vite produit alors un fichier JavaScript séparé par page.
Listes longues
Section intitulée « Listes longues »Pour des milliers de lignes, virtualiser (n’afficher que les lignes visibles) avec une bibliothèque comme TanStack Virtual, et paginer côté API.
npm run buildls -lh dist/assets/npx vite-bundle-visualizer # carte du contenu des fichiers JavaScriptLes React DevTools (extension du navigateur) affichent les rendus et leur durée. L’onglet Lighthouse des outils de développement évalue performance et accessibilité.
Construire pour la production
Section intitulée « Construire pour la production »npm run buildnpm run preview # contrôle local de dist/dist/ contient index.html et des fichiers dans assets/ dont le nom comprend une empreinte du contenu (index-3f9a2b.js) : ils peuvent être mis en cache durablement.
Servir avec Caddy
Section intitulée « Servir avec Caddy »exemple.com { root * /var/www/monapp encode zstd gzip
@assets path /assets/* header @assets Cache-Control "public, max-age=31536000, immutable"
header { Strict-Transport-Security "max-age=31536000" X-Content-Type-Options "nosniff" Referrer-Policy "strict-origin-when-cross-origin" -Server }
handle /api/* { reverse_proxy 127.0.0.1:3000 }
handle { try_files {path} /index.html file_server }}| Bloc | Rôle |
|---|---|
@assets |
Cache long sur les fichiers à empreinte |
handle /api/* |
Relaie l’API vers le serveur applicatif |
try_files {path} /index.html |
Repli : toute URL inconnue renvoie index.html, pour que React Router gère la route |
Ne pas mettre en cache longtemps index.html : il référence les nouveaux fichiers à chaque version. Voir Caddy : exemples réutilisables.
Déployer
Section intitulée « Déployer »npm run buildrsync -az --delete --dry-run dist/ utilisateur@serveur.exemple.com:/var/www/monapp/rsync -az --delete dist/ utilisateur@serveur.exemple.com:/var/www/monapp/Toujours lire la sortie du --dry-run. Pour déployer après chaque envoi sur le dépôt : Gitea Actions : exemples.
Variables d’environnement au build
Section intitulée « Variables d’environnement au build »Les variables VITE_* sont figées dans le JavaScript lors du build : changer la valeur impose de reconstruire. Pour une configuration modifiable sans rebuild, charger un fichier config.json au démarrage :
const config = await fetch('/config.json').then((r) => r.json());Sécurité
Section intitulée « Sécurité »- Aucun secret dans le code du navigateur (visible de tous).
- Échapper les contenus : React échappe par défaut ;
dangerouslySetInnerHTMLn’accepte que du HTML de confiance (ou nettoyé avec DOMPurify). - Jetons d’authentification : préférer des cookies
HttpOnlyetSameSiteàlocalStorage. - Mettre à jour les dépendances :
npm audit. - En-têtes de sécurité (
Content-Security-Policy) au niveau du serveur web.
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
| 404 en rechargeant une route | Repli sur index.html absent (try_files) |
| Page blanche après déploiement | Chemins des assets incorrects (base dans vite.config si l’application est servie dans un sous-dossier), console du navigateur |
| Ancienne version affichée | index.html mis en cache : ne pas lui donner de cache long |
| Erreur de chargement d’un fichier JavaScript après une mise à jour | Onglet ouvert avec l’ancien index.html : recharger |
| Application lente | Profiler, découpage du code, listes virtualisées |
Unexpected token '<' pour un fichier JavaScript |
Le serveur a renvoyé index.html à la place d’un fichier manquant |
| Appels d’API en échec en production | Reverse proxy /api/*, CORS |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Aucune propre à React. Sous Linux, la casse des noms de fichiers compte dans les imports.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Performance, Déployer avec Vite
- Suite : Dépannage