Que fait Guide de Développement Frontend ?
Vue d'ensemble
Ce guide couvre le développement frontend moderne avec React, Vue, Angular et Svelte, y compris l'architecture des composants, l'optimisation des performances, l'accessibilité et les tests. Utilisez-le lors de la construction d'applications web, de bibliothèques de composants ou de l'optimisation des performances frontend.
Règles de Décision sur le Framework et la Mise en Page
- Lors du choix d'un framework, faites correspondre l'expertise de l'équipe et les contraintes du projet ; par défaut, utilisez React pour les besoins d'un large écosystème, Vue pour l'amélioration progressive de pages existantes, Svelte pour les applications où la taille du bundle est critique, et Angular lorsque le projet nécessite un framework complet et avisé avec DI et routage intégrés.
- Lors de l'implémentation d'un design, utilisez CSS Grid pour les mises en page bidimensionnelles et Flexbox pour l'alignement unidimensionnel des composants ; évitez le positionnement absolu à des fins de mise en page car il casse le réarrangement responsive.
- Lors de la construction d'une bibliothèque de composants, exposez chaque composant comme une exportation nommée avec une interface TypeScript pour les props, une histoire Storybook et un test unitaire -- les composants sans ces trois éléments ne sont pas fusionnés.
- Lors de l'intégration avec des API backend, centralisez la logique de récupération dans une couche client API typée (par exemple, un seul module
api.tsutilisantfetchouaxiosavec intercepteurs) de sorte que les en-têtes d'authentification, les transformations d'erreur et les tentatives soient gérées en un seul endroit.
Règles de Décision sur les Performances
- Lorsque le Largest Contentful Paint d'une page dépasse 2,5 secondes dans Lighthouse CI, traitez-le comme un bogue bloquant -- profilez avec l'onglet Performances de Chrome DevTools et corrigez le plus grand goulot d'étranglement avant de fusionner.
- Lors de l'ajout d'animations, utilisez les propriétés CSS
transformetopacity(uniquement pour le compositeur) plutôt quewidth,heightoutop/leftpour éviter de déclencher des recalculs de mise en page qui provoquent des à-coups. - Lorsque l'application a besoin d'une prise en charge hors ligne, enregistrez un service worker avec une stratégie cache-first pour les actifs statiques et une stratégie network-first pour les requêtes API, en revenant aux réponses mises en cache lorsqu'il est hors ligne.
- Lorsque le bundle JS initial dépasse le budget (par exemple, 200 Ko compressé), ajoutez un fractionnement de code basé sur les routes avec
React.lazy()ouimport()dynamique et reportez les scripts non critiques en dessous de la ligne de flottaison. - Lors de la prise en charge de navigateurs plus anciens, définissez une configuration browserslist et laissez l'outil de build (Vite, Webpack) faire le polyfill automatiquement ; n'ajoutez pas manuellement de polyfills ou de vérifications de fonctionnalités, sauf si la couverture de browserslist est insuffisante.
- Lors de l'ajout d'images, utilisez
<picture>avec des sources WebP/AVIF et des attributs expliciteswidth/heightpour empêcher le décalage de mise en page ; pour les images en dessous de la ligne de flottaison, ajoutezloading="lazy". - Lorsqu'une route n'est pas nécessaire au chargement initial de la page, enveloppez-la dans
React.lazy()(ou l'équivalent du framework) avec un fallback<Suspense>afin que le bundle principal exclue le code de cette route. - Lors de la diffusion d'actifs statiques, configurez le CDN ou le serveur pour définir
Cache-Control: public, max-age=31536000, immutablesur les noms de fichiers à contenu haché etno-cachesurindex.html.
Règles de Décision sur l'Accessibilité
- Lors de la construction d'un composant interactif, ajoutez des attributs ARIA, des gestionnaires de clavier (
Entrée,Espace,Échapselon le cas) et testez avec axe-core avant de marquer la tâche comme terminée. - Lors de la construction de formulaires, associez chaque
<input>avec une<label>viahtmlFor/id, fournissez des messages d'erreur visibles liés avecaria-describedby, et assurez-vous que le formulaire est entièrement utilisable avec une navigation uniquement au clavier. - Lors de l'utilisation de la couleur pour transmettre un sens (par exemple, états d'erreur, badges de statut), incluez toujours un indicateur secondaire (icône, texte, motif) afin que les utilisateurs daltoniens puissent distinguer les états.
- Lors de l'ajout d'une fenêtre modale ou d'un menu déroulant, piégez le focus à l'intérieur de l'élément lorsqu'il est ouvert et retournez le focus à l'élément déclencheur à la fermeture ; testez en parcourant l'ensemble du flux à l'aide de la touche de tabulation sans souris.
- Lorsqu'une pull request ajoute un nouveau composant interactif, la PR doit inclure un test d'intégration axe-core qui affirme zéro violation WCAG 2.1 AA avant de pouvoir être fusionnée.
Règles de Décision pour le Débogage CSS
Lorsqu'une mise en page se casse, diagnostiquez par symptôme :
- L'enfant Flex dépasse son conteneur : Ajoutez
min-width: 0(ligne) oumin-height: 0(colonne) à l'enfant flex. Les éléments flex par défaut ontmin-width: auto, ce qui empêche le rétrécissement en dessous de la taille du contenu. - Les éléments de la grille ignorent la largeur de colonne : Utilisez
minmax(0, 1fr)au lieu de1fr.1frbrut signifieminmax(auto, 1fr), ce qui permet au contenu de pousser la colonne plus large que prévu. position: stickyne colle pas : Vérifiez chaque ancêtre pouroverflow: hidden,overflow: autoouoverflow: scroll. Chacun d'eux crée un nouveau contexte de défilement qui contient l'élément sticky. Vérifiez également que l'élément a une valeurtop/bottomdéfinie.- L'élément centré avec
margin: autone se centre pas : Vérifiez que l'élément a unewidthexplicite (bloc) ou que le parent adisplay: flex(enfant flex).margin: autone fait rien sur les éléments de bloc pleine largeur. z-indexne fonctionne pas : L'élément a besoin deposition: relative/absolute/fixed/stickypour créer un contexte d'empilement. Vérifiez également si un ancêtre crée un contexte d'empilement (viatransform,opacity < 1,filterouwill-change) qui limite la portée du z-index.- Espace entre les éléments inline-block/inline : Les espaces blancs en HTML créent des espaces. Correction : utilisez
display: flexsur le parent (préféré), ou définissezfont-size: 0sur le parent et réinitialisez sur les enfants. - Espace de 1px entre les éléments adjacents : Rendu sous-pixel. Correction : utilisez
outlineau lieu deborderpour le débogage, ou définissezbackgroundsur le parent pour masquer l'espace. - La troncature de texte avec des points de suspension ne fonctionne pas : Nécessite les trois :
overflow: hidden,white-space: nowrap,text-overflow: ellipsis. Pour la troncature multiligne, utilisez-webkit-line-clampavecdisplay: -webkit-boxet-webkit-box-orient: vertical. - Les requêtes de conteneur ne s'appliquent pas : Vérifiez que l'ancêtre a
container-type: inline-size(ousize). L'élément lui-même ne peut pas être son propre conteneur -- la requête doit faire référence à un parent.
Règles de Décision sur les Outils de Build
- Vite (par défaut) : Utilisez pour tous les nouveaux projets. Serveur de développement instantané via ESM natif, HMR rapide, builds de production basés sur Rollup. Si le projet utilise des dépendances CommonJS uniquement qui échouent avec Vite, ajoutez
optimizeDeps.includepour ces packages -- ne passez pas à Webpack. - Webpack : Utilisez uniquement pour les projets existants qui l'utilisent déjà, ou lorsqu'un plugin spécifique à Webpack n'a pas d'équivalent Vite (rare). Migrez vers Vite lorsque l'occasion se présente (voir les Règles de Décision de Migration).
- Turbopack : Utilisez uniquement dans Next.js 14+ (
next dev --turbo). Pas encore utilisable de manière autonome. Fournit des builds de développement plus rapides que Webpack pour les projets Next.js. Si les builds sont déjà rapides (<5s), ne vous embêtez pas à basculer. - esbuild : Utilisez pour le regroupement de bibliothèques, les scripts ou les outils CLI -- pas pour les applications complètes. Aucune gestion de point d'entrée HTML, aucun fractionnement de code par route. Utilisez
tsup(wrapper esbuild) pour publier des packages npm. - SWC vs Babel : Utilisez SWC (via le plugin Vite ou par défaut Next.js). SWC est 20 à 70 fois plus rapide pour les transformations. Utilisez Babel uniquement si un projet dépend d'un plugin Babel uniquement sans équivalent SWC (de plus en plus rare).
- Outillage Monorepo : <5 packages = espaces de travail npm/pnpm, pas d'outil supplémentaire. 5-20 packages = Turborepo pour la mise en cache des tâches. >20 packages ou polyglotte = Nx. N'ajoutez jamais d'outillage monorepo à un projet à package unique.
Règles de Décision sur le SSR et les Composants Serveur
Quand utiliser SSR vs CSR vs SSG
- SSG (Génération de Site Statique) : Utilisez pour le contenu qui change moins d'une fois par heure (pages marketing, documentation, articles de blog). Construisez au moment du déploiement. TTFB le plus rapide possible.
- SSR (Rendu Côté Serveur) : Utilisez pour le contenu personnalisé (tableaux de bord, profils utilisateur), les pages critiques pour le SEO avec des données dynamiques, ou les pages où des données obsolètes sont inacceptables. Ajoutez la latence du serveur à chaque requête -- mettez en cache de manière agressive avec
Cache-Controlou CDN. - CSR (Rendu Côté Client) : Utilisez pour les pages réservées aux utilisateurs authentifiés (panneaux d'administration, outils internes) où le SEO n'a pas d'importance et où l'interactivité est la priorité. Le plus simple à construire et à déployer (hébergement statique).
- ISR (Régénération Statique Incrémentielle) : Utilisez pour les pages qui sont principalement statiques mais qui ont besoin de mises à jour périodiques (listes de produits, pages de prix). Définissez l'intervalle
revalidateen fonction de la durée pendant laquelle les données peuvent être obsolètes : 60s pour les prix, 3600s pour les articles de blog.
Règles de Décision sur les Composants Serveur React (RSC)
- Par défaut, utilisez les Composants Serveur : Chaque composant est un Composant Serveur sauf s'il a besoin d'interactivité. Si un composant a
onClick,useState,useEffectou des API du navigateur -- il doit être un Composant Client ('use client'). - Récupération de données : Récupérez les données dans les Composants Serveur avec
async/awaitdirectement -- pas deuseEffect, pas de TanStack Query, pas d'états de chargement nécessaires. Les données sont résolues avant que le HTML ne soit envoyé. - Auth dans les Composants Serveur : Lisez la session/cookie dans un Composant Serveur et passez l'objet utilisateur comme prop aux Composants Clients. Ne lisez jamais les cookies ou les sessions dans les Composants Clients -- ils s'exécutent sur le client.
- Quand utiliser les Actions Serveur vs les routes API : Utilisez les Actions Serveur (
'use server') pour les soumissions de formulaire et les mutations appelées depuis l'interface utilisateur. Utilisez les routes API (/api/*) pour les webhooks, les intégrations tierces ou les points de terminaison appelés par des services externes. - Partage d'état entre les Composants Serveur et Client : Passez les données sérialisables comme props du Serveur → Client. Si vous avez besoin d'un état côté client dérivé des données du serveur, initialisez
useStateavec la prop du serveur et gérez les mises à jour sur le client. - Grands ensembles de données : Diffusez avec les limites
<Suspense>. Enveloppez le Composant Serveur lent dans<Suspense fallback={<Skeleton />}>. Le squelette se rend immédiatement ; le composant lent se diffuse lorsqu'il est prêt. Placez les limites Suspense au niveau de sections UI significatives (barre latérale, contenu principal, commentaires) -- pas autour de chaque composant.
Arbre de Décision des Erreurs d'Hydratation
- Erreur : "Text content does not match" : Une valeur diffère entre le rendu serveur et client. Causes courantes :
Date.now(),Math.random()ounew Date().toLocaleString()dans le rendu → déplacez versuseEffect+useState.- Rendu conditionnel
typeof window !== 'undefined'→ utilisezuseEffectpour définir un indicateurhasMounted. - Extensions de navigateur injectant des nœuds DOM → pas votre bogue, mais testez en mode navigation privée pour confirmer.
- Erreur : "Hydration failed because the server rendered HTML didn't match" : Une différence structurelle (éléments différents). Causes courantes :
<p>imbriqué dans<p>, ou<div>dans<p>→ corrigez l'imbrication, la spécification HTML ne le permet pas.- Un composant tiers se rend différemment sur le serveur vs le client → enveloppez dans
dynamic(() => import(...), { ssr: false }). - Balises de fermeture manquantes ou balises auto-fermantes là où HTML nécessite une fermeture explicite.
Workflow de Débogage des Performances
Lorsqu'une page est lente, suivez cette séquence -- ne sautez pas d'étapes :
Étape 1 : Identifier le type de goulot d'étranglement
- Exécutez Lighthouse. Vérifiez quelle métrique échoue :
- LCP >2.5s : Le plus grand élément visible se charge trop lentement. Allez à l'Étape 2.
- FID/INP >200ms : L'interaction utilisateur est bloquée par JavaScript. Allez à l'Étape 3.
- CLS >0.1 : Décalages de mise en page après le premier rendu. Allez à l'Étape 4.
Étape 2 : Corriger le LCP
- Vérifiez ce qu'est l'élément LCP (Lighthouse le montre). Généralement : image hero, texte de titre ou vidéo.
- Si image : Ajoutez
priority(Next.js) oufetchpriority="high". Ajoutezwidth/heightexplicites. Servez en WebP/AVIF. Si servie depuis un CDN, vérifiez les en-têtes de cache. - Si texte : Vérifiez les polices bloquant le rendu. Utilisez
font-display: swapoufont-display: optional. Préchargez le fichier de police critique avec<link rel="preload" as="font" crossorigin>. - Si bloqué par JS : Le bundle est trop volumineux. Vérifiez l'Étape 3. L'élément LCP ne peut pas s'afficher tant que le JS qui le crée n'est pas chargé et exécuté.
- Vérifiez le temps de réponse du serveur (TTFB). Si TTFB >600ms, le goulot d'étranglement est le backend ou le CDN -- pas le frontend.
Étape 3 : Corriger l'INP (Interaction to Next Paint)
- Ouvrez Chrome DevTools → Performances → enregistrez une interaction de clic/tape.
- Trouvez la Longue Tâche (barre jaune >50ms). Cliquez dessus pour voir la pile d'appels.
- Si la longue tâche est votre code : Divisez le travail en morceaux plus petits avec
requestIdleCallback,scheduler.yield()(Chrome 115+), ousetTimeout(fn, 0)pour céder la main au navigateur entre les images. - Si la longue tâche est un re-rendu React : Ouvrez le Profileur React DevTools. Trouvez le composant qui se re-rend. Correctifs courants :
React.memo(enfants coûteux),useMemo(valeurs dérivées), ou déplacez l'état plus près de l'endroit où il est utilisé. Si >500 composants se re-rendent sur un seul changement d'état, l'état est trop haut dans l'arbre. - Si la longue tâche est un script tiers (analytiques, publicités) : Reportez avec l'attribut
asyncoudefer, ou chargez aprèsrequestIdleCallback.
Étape 4 : Corriger le CLS
- Vérifiez quel élément se déplace (Lighthouse le montre, ou utilisez DevTools → "Layout Shift Regions").
- Image/vidéo sans dimensions : Ajoutez les attributs
widthetheight(ouaspect-ratioCSS). Le navigateur réserve l'espace avant le chargement de l'actif. - Échange de police : La police de secours a des métriques différentes de la police web. Utilisez
size-adjustdans@font-facepour faire correspondre les métriques, ou utilisezfont-display: optionalpour éliminer complètement l'échange. - Contenu dynamique injecté au-dessus de la ligne de flottaison : Publicités, bannières, notifications de cookies. Réservez l'espace avec
min-heightsur le conteneur. Si la hauteur du contenu varie, utilisezcontain: layoutpour empêcher la propagation des déplacements. - CSS à chargement tardif : Si une feuille de style se charge après le premier rendu et modifie la mise en page visible, incorporez le CSS critique ou préchargez la feuille de style.
Règles de Décision sur la Qualité du Code
- Lors de l'écriture de tests, exigez que chaque composant ait au moins un test unitaire couvrant son chemin de rendu principal et un test d'interaction (clic, clavier) -- enforce via une porte de couverture CI d'au moins 80 % de couverture de ligne.
- Lors du démarrage d'un projet, activez
strict: truedanstsconfig.jsondès le premier jour ; l'ajout du mode strict après coup est exponentiellement plus difficile à mesure que la base de code grandit. - Lorsqu'un appel API ou une opération asynchrone échoue, affichez un message d'erreur visible à l'utilisateur avec une action de réessai -- n'avalez jamais les erreurs en silence et n'affichez pas le texte d'exception brut.