Optimisation des performances UI
1) Quoi compter « rapide »
TTFB (temps jusqu'au premier octet) est une réponse rapide serveur/CDN.
LCP (Largest Contentful Paul) - le contenu « principal » est apparu rapidement.
INP (Interaction to Next Paint) : Réactivité lors de l'interaction.
CLS (Cumulative Layout Shift) - Pas de « gigue » de l'interface.
TTI (Time to Interactive) - quand tout répond déjà.
Points de repère recommandés : LCP ≤ 2. 5 s, INP ≤ 200 ms, CLS ≤ 0. 1 (pour le 75e percentile des vrais utilisateurs).
2) Processus : Mesurer → trouver les goulets d'étranglement → fixer les budgets
1. Mesurer : RUM (utilisateurs réels, percents par pays/réseaux/devis) + synthétique (Lighthouse/navigateurs).
2. Trouver : profileur Performance (tâches longues> 50 ms, layout thrashing, renders superflus).
3. Fixer : budgets (poids JS/CSS/polices, LCP/INP) et « lignes rouges » dans CI.
3) Réseau et chargement des ressources
3. 1 HTTP et priorités
Activer le HTTP/2/3, compression Brotli.
'preconnect' aux domaines critiques ; 'dns-prefetch' pour les domaines secondaires.
'preload' pour les ressources critiques (héros-image, police de base).
'fetchpriority =' high/low 'et' priority 'de l'indice où il est maintenu.
3. 2 Mise en cache
Statique avec hachage de fichier : 'Cache-Control : public, max-age = 31536000, immutable'.
HTML - court TTL + stale-while-revalidate via CDN.
ETag/Last-Modified et Service Worker pour les visites hors ligne/répétées.
4) Code : plus petit, plus tard, « plus régulier »
4. 1 Assemblage
Tree-shaking, minify (в т.ч. dead-code-elim).
Code-splitting par itinéraire/widgets, importation dynamique.
Évitez les paquets lourds « globaux » dans le gang de base (moment → Intl/Day. js).
4. 2 Rendu et livraison HTML
SSR/ISR/streaming : donner le cadre et le contenu principal en premier.
Partial/Islands hydration : Hydrogéner uniquement les zones interactives.
Defer n'est pas critique : '<script type = « module » defer>'.
4. 3 Spécificités réactives (si vous utilisez React)
`React. lazy '+' Suspense 'pour les widgets paresseux.
'StartTransition 'et' useDeferredValue 'pour les filtres/recherches lourds.
RSC (Server Components) - Calcul sur le serveur, moins de JS sur le client.
Sélecteurs dans la pile (zustand/redux) : signez le composant sur les tranches plutôt que sur la pile entière.
5) Rendu et condition : où « freine »
5. 1 Isolation des revendeurs
Fractionner de gros composants, memoiser ('memo', 'useMemo', 'useCallback').
Les clés de liste sont stables ; ne créez pas de nouvelles fonctions/objets dans les props inutiles.
Évitez le contexte « global » pour les données qui changent souvent - utilisez des sélecteurs ou des bus d'événements.
5. 2 Virtualisation et grandes listes
Feuilles/tableaux → virtualisation (render window).
Pagination/infinit-scroll avec backpressure (ne chargez pas 100k lignes à la fois).
Initialisation retardée des widgets lourds en dehors de la fenêtre.
5. 3 Layout & paint
content-visibility: auto; pour les sections cachées (le navigateur ne rend pas l'invisible).
contain et 'contain-intrinsic-size' pour les tailles prévisibles.
Évitez les lectures-enregistrements fréquentes de layout en vrac (layout thrashing) ; regrouper les mesures.
utiliser le will-change dosé (autrement mémoire supplémentaire/couches).
6) Images et graphiques
Formats : AVIF/WebP (fallback sur PNG/JPEG).
Approche responsive : 'srcset' + 'sizes', density-based pour la rétine.
« loading = » lazy « » pour les images non héroïques ; priority/preload - uniquement pour le candidat LCP.
Плейсхолдеры avec les montants fixés → il n'y a pas de sauts CLS.
Canvas/charts : offscreen-canvas et Web Worker pour les calculs ; Batching redessiner.
7) Polices et texte
Une ou deux font variables au lieu de beaucoup de caractères.
'Font-display : swap '/' optional ', preload pour l'image de base.
'size-adjust' pour réduire le « saut » lors du remplacement de la police.
Les polices fallback locales avec des métriques similaires.
8) CSS et animations
L'inline CSS critique (<14-20 kB), le reste est retardé.
Supprimer les styles inutilisés (Purge/CSSTree).
Des animations, si possible, sur le module/opacity ; Respecter 'prefers-reduced-motion'.
Évitez les cascades profondes et les sélecteurs éclatants.
9) Web Workers, flux et tâches lourdes
Tous les CPU lourds sont dans Worker (parsing, tri, agrégation, ML).
API de streaming ('ReadableStream', 'fetch' avec les flux) pour les réponses longues.
Écraser les tâches sur les cuves via requestIdleCallback '/microtasques pour rester réactif.
10) Stabilité de la mise en page (CLS)
Réservez un espace sous l'élément LCP (image/widget).
N'insérez pas de bannières/rubans sans dimensions fixes.
Tultips/toasts asymétriques - ne pas déplacer le contenu ; utiliser des couches/portails.
11) Exemples de prélèvements
Police critique et image LCP
html
<link rel="preload" href="/fonts/Inter. var. woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" as="image" href="/hero. avif" imagesrcset="/hero. avif 1x, /hero@2x. avif 2x" fetchpriority="high">
Initialisation fainéante et sûre du widget
js const Widget = React. lazy(() => import('./Widget'));
function Section() {
const inView = useInViewport('#sec');
return <div id="sec">{inView? <React. Suspense fallback={null}><Widget/></React. Suspense>: null}</div>;
}
Stabilisation de la mise en page
css
.hero {
content-visibility: auto;
contain: layout paint;
contain-intrinsic-size: 720px 320px ;/LCP reserve/
}
12) Contrôle des régressions et budgets
Bundle-budget : total JS ≤ N kB, CSS ≤ M kB, initial-chunk ≤ K kB.
Web-Vitals en CI (émulé) + alertes RUM (sur percentiles).
Analyse de bandle : source-map-explorer/analyseur dans PR.
Repères de performance des composants (rendu 10k des éléments, temps de réaction).
13) Anti-modèles
Chargez « tout et à la fois » : graphiques, éditeurs, cartes dans le premier écran.
Un énorme stat mondial → des reranders en cascade.
Images 2-4 × de la taille souhaitée, sans 'srcset/sizes'.
Cycles synchrones longs sur le flux principal.
'outline : none' et focus personnalisés sans optimisation - interfèrent avec les indicateurs de rendu.
Animations par 'top/left' (casser le schéma et déclencher le reflow).
14) Chèque écran
- LCP ≤ 2. 5 c sur le trafic 3G/mobile, CLS ≤ 0. 1, INP ≤ 200 ms
- Ressources critiques : preload/priorités ; le reste est defer/lazy
- Bandles : code-split, pas de dépendances superflues
- Virtualisation des listes/tables, initialisation retardée des widgets lourds
- Images : AVIF/WebP, 'srcset/sizes', 'loading =' lazy '
- Polices : variable + 'font-display', preload seulement le bon
- CSS : inline critique, Purge, « content-visibility » et « contain » le cas échéant
- Workers/idle pour le calcul lourd
- Budgets et Web-Vitals connectés aux dashboards/alerts
15) Plan de mise en oeuvre (3 itérations)
Itération 1 - Victoires rapides (1-2 semaines)
Activer le Brotli/HTTP-2/3, CDN. Ressources CSS et preload LCP critiques.
Mettre des widgets lourds dans des importations dynamiques.
Images → AVIF/WebP + 'srcset'. Polices : 'font-display : swap'.
Itération 2 - Améliorations structurelles (3-4 semaines)
Code-split le long des itinéraires, analyse des bandles, élimination des libas « lourds ».
Virtualisation des listes, visibilité du contenu, contain-intrinsic-size.
Mettre en œuvre SSR/streaming/îles (lorsque pertinent).
RUM avec Web-Vitals, budgets en CI.
Itération 3 - Échelle et stabilité (continu)
Workers/offscreen-canvas, batching, startTransition/deferredValue.
Audit régulier de perf, auto-jest de régression, formation de l'équipe.
16) Mini-FAQ
Qu'est-ce qui accélère le plus sur le mobile ?
Réduction du JS initial, SSR/streaming et optimisation de l'image LCP.
Avez-vous toujours besoin de SSR ?
Non. Si la page est interactive dynamiquement et mal mise en cache - islands/partial hydration peut être mieux.
Pourquoi l'INP est-il mauvais avec un gang « léger » ?
Il est probable que de longues tâches (tri, graphiques) sur le flux principal - sortir dans Worker et fractionner les tâches.
Résultat
L'IU rapide est un ensemble de disciplines : priorités réseau et cache, bandles plus petits et plus récents, rendu prévisible sans sauts, images et polices économiques, et contrôle constant des métriques dans le monde réel. Entrez les budgets, automatisez les vérifications et apprenez à l'équipe à penser à la vitesse à chaque étape - de sorte que l'interface restera rapide aujourd'hui et dans un an.