Performances Web : la règle des 100 ms et la nouvelle métrique INP
Google a modifié les règles avec INP (Interaction to Next Paint). optimisation pour React Hydration et Edge Caching.
La vitesse n’est pas un « agréable à avoir ». La vitesse est la seule fonctionnalité dont chaque utilisateur bénéficie. Amazon a constaté que chaque 100 ms de latence leur coûtait 1 % de ventes. Walmart a constaté qu’une amélioration du temps de chargement d’une seconde augmentait les conversions de 2 %. En 2025, la barre est plus haute. Les Core Web Vitals de Google sont passés de LCP (Loading) à INP (Interaction to Next Paint). Il ne suffit plus de charger rapidement. Vous devez répondre rapidement.
Pourquoi Maison Code en parle
Chez Maison Code Paris, nous agissons comme la conscience architecturale de nos clients. Nous héritons souvent de stacks “modernes” construites sans compréhension fondamentale de l’échelle.
Nous abordons ce sujet car il représente un point de pivot critique dans la maturité de l’ingénierie. Une mise en œuvre correcte différencie un MVP fragile d’une plateforme résiliente de niveau entreprise.
Pourquoi Maison Code obsède plus de 100 ms
La vitesse est notre marque. Nous ne nous contentons pas « d’optimiser les images ». Nous réorganisons l’ensemble du pipeline de livraison.
- Infrastructure : Nous déployons vers le Edge (Vercel/Cloudflare) pour être à moins de 50 ms de l’utilisateur.
- Hydratation : nous utilisons l’hydratation sélective pour rendre le « bouton d’achat » interactif avant même le chargement du pied de page.
- Résultat : nos clients réussissent systématiquement les Core Web Vitals, ce qui entraîne une augmentation mesurée du référencement de 15 à 20 %. Nous traitons les budgets de performance comme les budgets financiers. Les dépenses excessives ne sont pas une option.
L’API des règles de spéculation
La requête réseau la plus rapide est celle que vous ne faites pas. En 2025, nous utilisons l’API Speculation Rules pour pré-afficher les pages avant que l’utilisateur clique. Il ne s’agit pas d’une « prélecture » standard. Chrome construit littéralement le DOM dans un onglet d’arrière-plan. Lorsque l’utilisateur clique, la transition est de 0 ms. Instantané.
<!-- Injection de règles de spéculation -->
<script type="speculationrules">
{
"pré-rendu": [
{
"source": "document",
"où": {
"et": [
{ "href_matches": "/products/*" },
{ "selector_matches": "a:hover" }
]
}
}
]
}
</script>
Sécurité et utilisation des données
L’une des préoccupations liées à la spéculation concerne l’utilisation des données. Si nous préaffichons 10 pages et que l’utilisateur en visite 0, nous gaspillons de la bande passante. Le navigateur est intelligent. Il spécule seulement si :
- L’utilisateur est en Wi-Fi (pas en mode Data Saver).
- L’appareil dispose de suffisamment de mémoire. Cependant, pour un site e-commerce, la « Next Action » est extrêmement prévisible. Sur un PDP (page de détails du produit), l’action suivante est soit « Ajouter au panier », soit « Retour à la collection ». La spéculation sur ces deux itinéraires donne un taux de réussite de 90 %.
INP : Le tueur de réaction ?
INP mesure le temps entre « Clic » et « Peindre ». L’hydratation de React est l’ennemi de l’INP. Si un utilisateur clique sur « Ajouter au panier » pendant que React hydrate le pied de page, le fil de discussion principal est bloqué. Le bouton ignore le clic. Le score INP passe à 400 ms (médiocre). Google pénalise votre référencement.
Optimisation de l’INP dans Headless
- Hydratation sélective : Hydratez uniquement les composants visibles. (Voir Atomic Design pour l’isolation des composants).
- Web Workers : déplacez la logique lourde (Analytics, GTM) vers un Web Worker via Partytown.
- API de transition : utilisez
useTransitionpour marquer les mises à jour non urgentes.
// Implémentation de React 19 useTransition
importer { useTransition } depuis 'react' ;
fonction AddToCart({ identifiant }) {
const [isPending, startTransition] = useTransition();
const handleClick = () => {
// Urgent : mettre à jour l'interface utilisateur immédiatement
setOptimisticCartCount(c => c + 1);
// Non urgent : requête réseau / mise à jour de l'état
startTransition(() => {
addToCart(id);
});
} ;
retour (
<button onClick={handleClick} désactivé={isPending}>
{est en attente ? 'Ajout...' : 'Ajouter au panier'}
</bouton>
);
}
The Edge : la géographie compte
Si votre serveur est en Virginie (us-east-1) et que votre client est à Paris, la vitesse de la lumière impose une pénalité de 100 ms. Vous ne pouvez pas battre la physique. Vous devez déplacer le calcul. Edge Rendering (Oxygen/Vercel) exécute la logique SSR dans un centre de données le plus proche de l’utilisateur.
Périmé pendant la revalidation (SWR)
Nous ne voulons pas atteindre l’origine de chaque demande. Nous utilisons la stratégie de cache SWR, un avantage essentiel de Headless Architecture.
- L’utilisateur A visite « /products/shoe ».
- Edge sert la version obsolète (instantanée).
- Edge récupère la nouvelle version en arrière-plan.
- L’utilisateur B obtient la version Fresh.
Dans les en-têtes Remix/Hydrogen :
exporter les en-têtes de fonction() {
retourner {
'Cache-Control' : 'public, max-age=60, s-maxage=3600, stale-while-revalidate=86400',
} ;
}
Optimisation d’image : AVIF est roi
Oubliez WebP. AVIF est la norme.
Il est 30 % plus petit que WebP et prend en charge les gammes de couleurs HDR (essentielles pour la mode).
Le CDN de Shopify prend en charge le formatage automatique AVIF.
Forcez toujours format=auto dans votre chargeur d’image.
La stratégie “LQIP”
Espaces réservés pour les images de mauvaise qualité. Pendant le chargement de l’image haute résolution, affichez une version floue de 10 px. Cela évite le “Layout Shift” (CLS) et donne la perception de vitesse. Nous générons des LQIP au moment de la construction ou via une fonction sans serveur.
Scripts tiers : The Silent Killer
Les agences adorent installer des scripts. Hotjar, Klaviyo, Yotpo, Facebook Pixel, TikTok Pixel, Snap Pixel. Chacun consomme 50 ms de temps de thread principal. Total = 300 ms de blocage.
Le problème avec “Async”
Les développeurs pensent que « Async » signifie « Non bloquant ». Cela signifie « Récupération non bloquante ». Mais l’Exécution bloque. Lorsque le pixel Facebook s’exécute, il gèle le thread principal pour gratter le DOM.
Solution : GTM côté serveur
Déplacez les pixels vers le serveur.
- Le navigateur envoie UN événement à votre serveur (par exemple
POST /api/events). - Votre serveur (GTM Server Container) le reçoit.
- Votre serveur le diffuse sur Facebook, TikTok, Google Ads. Aucun impact côté client. Bonus : il contourne les AdBlockers car la requête est dirigée vers votre propre domaine.
Solution : Partytown
Si vous DEVEZ exécuter des scripts côté client (comme Hotjar, qui nécessite le DOM), exécutez-les dans un Web Worker. Partytown est une bibliothèque qui transmet les mutations DOM d’un Worker au Main Thread. Il crée un bac à sable dans lequel des scripts tiers lourds peuvent s’exécuter sans geler l’interface utilisateur.
<script type="text/partytown" src="https://connect.facebook.net/en_US/fbevents.js"></script>
Stratégies de chargement de polices
La typographie est étonnamment lourde. Un fichier de police personnalisé (WOFF2) fait environ 50 Ko. Si vous bloquez le rendu jusqu’au chargement de la police (FOIT - Flash of Invisible Text), l’utilisateur regarde un écran vide. Si vous affichez la police de secours (FOUT - Flash of Unstyled Text), la mise en page change.
La pile de chargement de polices parfaite
- Sous-ensemble : incluez uniquement les caractères dont vous avez besoin (Latin-1).
- Préchargement : utilisez
<link rel="preload">pour la police critique (en-tête). - Échange : utilisez
font-display: swap. Affichez le texte immédiatement dans Helvetica, puis passez à votre police. - Size Adjust : utilisez CSS
size-adjustpour que la police de secours occupe exactement le même espace que la police personnalisée. Cela élimine le changement de disposition.
@font-face {
famille de polices : « Bodoni Fallback » ;
src : local('Times New Roman');
neutralisation de la remontée : 90 % ;
neutralisation de la descente : 20 % ;
ajustement de la taille : 140 % ;
}
RUM vs données de laboratoire
Lighthouse (Lab Data) est une simulation. Cela suppose un Motorola G4 sur le réseau 3G. RUM (Real User Monitoring) est la réalité. Il mesure ce que vivent les utilisateurs réels. Vous avez peut-être un score Lighthouse de 100, mais si vos vrais utilisateurs utilisent de vieux iPhones dans un métro, vos données RUM afficheront un LCP de 3 secondes. Nous intégrons Vercel Analytics ou Datadog RUM pour suivre le p75 (75e percentile) des expériences réelles. Si votre p75 est vert, tout va bien. Si votre phare est à 100 mais que p75 est rouge, vous échouez.
Conclusion
La performance est une culture d’ingénierie. Vous devez disposer d’un Budget de performance. “Si ce PR ajoute 10 Ko au paquet, quelque chose d’autre doit disparaître.” Respectez la règle des 100 ms. Si cela prend plus de 100 ms, vous aurez l’impression d’être cassé. Les sites de commerce électronique les plus rapides ne se contentent pas de « se sentir » rapides. Ils se sentent invisibles. L’interface disparaît, ne laissant que l’envie et le produit.