Vercel React Best Practices
Guide complet d'optimisation des performances pour les applications React et Next.js, maintenu par Vercel. Contient 70 règles réparties en 8 catégories, classées par ordre de priorité d'impact pour guider le refactoring automatisé et la génération de code.
Quand l'utiliser
Consultez ces directives lorsque :
- Vous écrivez de nouveaux composants React ou des pages Next.js
- Vous implémentez du data fetching (côté client ou serveur)
- Vous révisez du code pour des problèmes de performance
- Vous refactorez du code React/Next.js existant
- Vous optimisez la taille du bundle ou les temps de chargement
Catégories de règles par priorité
| Priorité | Catégorie | Impact | Préfixe |
|---|---|---|---|
| 1 | Élimination des cascades | CRITIQUE | async- |
| 2 | Optimisation de la taille du bundle | CRITIQUE | bundle- |
| 3 | Performance côté serveur | ÉLEVÉ | server- |
| 4 | Data fetching côté client | MOYEN-ÉLEVÉ | client- |
| 5 | Optimisation des re-rendus | MOYEN | rerender- |
| 6 | Performance de rendu | MOYEN | rendering- |
| 7 | Performance JavaScript | FAIBLE-MOYEN | js- |
| 8 | Schémas avancés | FAIBLE | advanced- |
Référence rapide
1. Élimination des cascades (CRITIQUE)
async-cheap-condition-before-await- Vérifier les conditions synchrones peu coûteuses avant d'attendre les flags ou valeurs distantesasync-defer-await- Déplacer await dans les branches où il est réellement utiliséasync-parallel- Utiliser Promise.all() pour les opérations indépendantesasync-dependencies- Utiliser better-all pour les dépendances partiellesasync-api-routes- Démarrer les promesses tôt, attendre tard dans les routes APIasync-suspense-boundaries- Utiliser Suspense pour diffuser le contenu
2. Optimisation de la taille du bundle (CRITIQUE)
bundle-barrel-imports- Importer directement, éviter les fichiers barrelbundle-analyzable-paths- Privilégier les chemins d'import et de système de fichiers statiquement analysables pour éviter des bundles et traces trop largesbundle-dynamic-imports- Utiliser next/dynamic pour les composants lourdsbundle-defer-third-party- Charger les outils d'analyse et de journalisation après l'hydratationbundle-conditional- Charger les modules uniquement lorsque la fonctionnalité est activéebundle-preload- Précharger au survol/au focus pour une rapidité perçue
3. Performance côté serveur (ÉLEVÉ)
server-auth-actions- Authentifier les actions serveur comme les routes APIserver-cache-react- Utiliser React.cache() pour la déduplication par requêteserver-cache-lru- Utiliser un cache LRU pour la mise en cache entre requêtesserver-dedup-props- Éviter la sérialisation en double dans les props RSCserver-hoist-static-io- Déplacer les E/S statiques (polices, logos) au niveau du moduleserver-no-shared-module-state- Éviter l'état mutable partagé au niveau du module dans RSC/SSRserver-serialization- Minimiser les données transmises aux composants clientsserver-parallel-fetching- Restructurer les composants pour paralléliser les requêtesserver-parallel-nested-fetching- Enchaîner les requêtes imbriquées par élément dans Promise.allserver-after-nonblocking- Utiliser after() pour les opérations non bloquantes
4. Data fetching côté client (MOYEN-ÉLEVÉ)
client-swr-dedup- Utiliser SWR pour la déduplication automatique des requêtesclient-event-listeners- Dédupliquer les écouteurs d'événements globauxclient-passive-event-listeners- Utiliser des écouteurs passifs pour le défilementclient-localstorage-schema- Versionner et minimiser les données localStorage
5. Optimisation des re-rendus (MOYEN)
rerender-defer-reads- Ne pas s'abonner à un état uniquement utilisé dans les callbacksrerender-memo- Extraire le travail coûteux dans des composants mémorisésrerender-memo-with-default-value- Déplacer les props non primitives par défautrerender-dependencies- Utiliser des dépendances primitives dans les effetsrerender-derived-state- S'abonner à des booléens dérivés, pas aux valeurs brutesrerender-derived-state-no-effect- Dériver l'état pendant le rendu, pas dans les effetsrerender-functional-setstate- Utiliser setState fonctionnel pour des callbacks stablesrerender-lazy-state-init- Passer une fonction à useState pour les valeurs coûteusesrerender-simple-expression-in-memo- Éviter memo pour les primitives simplesrerender-split-combined-hooks- Diviser les hooks avec des dépendances indépendantesrerender-move-effect-to-event- Mettre la logique d'interaction dans les gestionnaires d'événementsrerender-transitions- Utiliser startTransition pour les mises à jour non urgentesrerender-use-deferred-value- Différer les rendus coûteux pour garder la saisie réactivererender-use-ref-transient-values- Utiliser des refs pour les valeurs transitoires fréquentesrerender-no-inline-components- Ne pas définir de composants à l'intérieur d'autres composants
6. Performance de rendu (MOYEN)
rendering-animate-svg-wrapper- Animer le wrapper div, pas l'élément SVGrendering-content-visibility- Utiliser content-visibility pour les longues listesrendering-hoist-jsx- Extraire le JSX statique en dehors des composantsrendering-svg-precision- Réduire la précision des coordonnées SVGrendering-hydration-no-flicker- Utiliser un script inline pour les données côté client uniquementrendering-hydration-suppress-warning- Supprimer les avertissements de divergence attendusrendering-activity- Utiliser le composant Activity pour afficher/masquerrendering-conditional-render- Utiliser l'opérateur ternaire, pas && pour les conditionnelsrendering-usetransition-loading- Privilégier useTransition pour l'état de chargementrendering-resource-hints- Utiliser les indices de ressources React DOM pour le préchargementrendering-script-defer-async- Utiliser defer ou async sur les balises script
7. Performance JavaScript (FAIBLE-MOYEN)
js-batch-dom-css- Grouper les changements CSS via des classes ou cssTextjs-index-maps- Construire une Map pour les recherches répétéesjs-cache-property-access- Mettre en cache les propriétés d'objets dans les bouclesjs-cache-function-results- Mettre en cache les résultats de fonctions dans une Map au niveau du modulejs-cache-storage- Mettre en cache les lectures de localStorage/sessionStoragejs-combine-iterations- Combiner plusieurs filter/map en une seule bouclejs-length-check-first- Vérifier la longueur du tableau avant une comparaison coûteusejs-early-exit- Retourner tôt des fonctionsjs-hoist-regexp- Déplacer la création de RegExp en dehors des bouclesjs-min-max-loop- Utiliser une boucle pour min/max au lieu de sortjs-set-map-lookups- Utiliser Set/Map pour des recherches O(1)js-tosorted-immutable- Utiliser toSorted() pour l'immuabilitéjs-flatmap-filter- Utiliser flatMap pour mapper et filtrer en une seule passejs-request-idle-callback- Différer le travail non critique au temps d'inactivité du navigateur
8. Schémas avancés (FAIBLE)
advanced-effect-event-deps- Ne pas mettre les résultats deuseEffectEventdans les dépendances d'effetadvanced-event-handler-refs- Stocker les gestionnaires d'événements dans des refsadvanced-init-once- Initialiser l'application une fois par chargementadvanced-use-latest- useLatest pour des références de callback stables
Comment l'utiliser
Lisez les fichiers de règles individuels pour des explications détaillées et des exemples de code :
rules/async-parallel.md
rules/bundle-barrel-imports.md
Chaque fichier de règle contient :
- Une brève explication de pourquoi c'est important
- Un exemple de code incorrect avec explication
- Un exemple de code correct avec explication
- Contexte supplémentaire et références
Document complet compilé
Pour le guide complet avec toutes les règles développées : AGENTS.md