--- name: web-vitals-performance description: >- Optimize real-world web performance according to Google Core Web Vitals (INP <= 200ms, LCP <= 2.5s, CLS <= 0.1). Enforces main thread budgets, scheduler.yield() task chunking, AVIF media pipelines, font metric overrides, and third-party script isolation. --- # Web Vitals & Real-World Performance Engineering Ce skill garantit que les interfaces atteignent les seuils d'excellence des **Core Web Vitals** officiels (LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1) mesurés sur le terrain (Google Chrome User Experience Report - CrUX). --- ## 🎯 Déclencheurs d'Activation Activez ce skill dès que : 1. Vous chargez des médias lourds (images d'en-tête, bannières, galeries, vidéos). 2. Vous intégrez des polices typographiques web (Google Fonts, polices locales). 3. Vous développez des interactions utilisateur riches susceptibles de bloquer le thread principal (recherche instantanée, filtrage de tableau de données, calculs lourds côté client). 4. Vous auditez ou optimisez les scores de performance d'une application avant son déploiement. --- ## ⚡ 1. Optimisation de l'INP (Interaction to Next Paint ≤ 200ms) L'INP a définitivement remplacé le FID. Il mesure le délai entre une action utilisateur (clic, frappe, tap) et le moment exact où le navigateur affiche la prochaine image. ### Règle d'Or : Budget du Thread Principal < 50ms Toute tâche JS dépassant 50ms est une « Long Task » qui dégrade l'INP. ### Découpage des Tâches Longues avec `scheduler.yield()` ```typescript // Utilitaire moderne pour rendre la main au navigateur pendant un traitement lourd async function yieldToMain() { if ('scheduler' in window && 'yield' in (window as any).scheduler) { await (window as any).scheduler.yield(); } else { // Fallback standard await new Promise((resolve) => setTimeout(resolve, 0)); } } export async function processLargeDataset(items: Array) { for (let i = 0; i < items.length; i++) { // Traitement de l'élément computeHeavyItem(items[i]); // Toutes les 50 itérations, on cède le contrôle au thread principal pour afficher les clics/peintures if (i % 50 === 0) { await yieldToMain(); } } } ``` --- ## 🚀 2. Optimisation du LCP (Largest Contentful Paint ≤ 2.5s) L'élément LCP (souvent l'image du Hero ou le titre H1 principal) doit être peint immédiatement : 1. **`fetchpriority="high"` Obligatoire** sur l'image LCP : ```html Tableau de bord de design ``` 2. **Préchargement des Polices Critiques** : ```html ``` 3. **Format AVIF Prioritaire** : Toujours servir l'AVIF en premier (gain de 20 à 35% de bande passante par rapport au WebP). --- ## 📐 3. Élimination Totale du CLS (Cumulative Layout Shift ≤ 0.1) Le décalage de mise en page survient lorsque des éléments changent de position pendant le chargement. ### Solutions Anti-CLS : 1. **Ratio d'aspect explicite** : Tout conteneur d'image ou vidéo doit avoir une propriété CSS `aspect-ratio` ou des attributs `width` et `height`. 2. **Espace réservé pour la typographie** : Utilisez `@font-face` avec des métriques de substitution pour éviter le saut entre police système et police web : ```css @font-face { font-family: 'Geist-Fallback'; src: local('Arial'); ascent-override: 92%; descent-override: 24%; size-adjust: 102%; } ``` 3. **Squelettes de chargement (Skeletons)** : Réservez précisément la hauteur des blocs de contenu asynchrones. --- ## 📦 4. Gestion des Scripts Tiers (Analytics & Trackers) Ne jamais insérer de balise `