Une page peut s’afficher vite et rester parfaitement stable, mais si rien ne se passe pendant une demi-seconde après un toucher sur un bouton, l’expérience est frustrante quand même. Le menu ne s’ouvre pas, le filtre n’est pas appliqué, le produit ne semble pas ajouté au panier, et l’utilisateur touche de nouveau, ou s’en va. L’Interaction to Next Paint, INP, est la métrique des Core Web Vitals qui mesure exactement cela : la rapidité avec laquelle la page répond à ce que fait l’utilisateur.
Ce que mesure l’INP
L’INP mesure le temps entre une interaction de l’utilisateur, c’est-à-dire un clic, un toucher sur l’écran ou une pression de touche, et le moment où le navigateur affiche l’image suivante, celle qui montre à l’utilisateur que quelque chose s’est produit. Il ne suffit pas que le code commence à répondre : ce qui compte, c’est le moment où la réponse devient visible.
Depuis mars 2024, l’INP a remplacé le First Input Delay parmi les Core Web Vitals. La différence est substantielle : le FID ne mesurait que le délai de la première interaction, alors que l’INP prend en compte toutes les interactions de la visite et leur durée entière. Les seuils, au 75e percentile des visites réelles, sont les suivants : en moins de 200 millisecondes, le résultat est bon ; entre 200 et 500, il est à améliorer ; au-delà de 500, il est médiocre.
L’anatomie d’une interaction
Chaque interaction traverse trois phases, et chacune peut être responsable d’un INP élevé :
- Délai d’entrée (input delay) : le temps que l’interaction attend parce que le thread principal du navigateur est occupé par autre chose, par exemple un script tiers.
- Traitement (processing) : le temps nécessaire pour exécuter le code qui répond à l’événement, c’est-à-dire les gestionnaires attachés au clic ou à la touche.
- Présentation (presentation) : le temps que met le navigateur pour recalculer les styles et la mise en page et afficher la nouvelle image.
Distinguer les trois phases est essentiel, car les remèdes diffèrent. Un délai d’entrée élevé indique un thread principal surchargé de travail sans rapport avec l’interaction ; un temps de traitement long indique des gestionnaires d’événements trop lourds ; une présentation lente indique une page coûteuse à réafficher, souvent à cause d’un DOM très volumineux ou de modifications qui forcent le navigateur à recalculer plusieurs fois la mise en page.
Quelle interaction devient l’INP
Pendant une visite, l’utilisateur interagit de nombreuses fois, et le navigateur mesure chaque interaction. L’INP de la visite est la latence de l’une des pires : pour la plupart des pages, avec moins de cinquante interactions, il coïncide avec la plus lente ; pour les pages comptant un très grand nombre d’interactions, comme les applications web ou les jeux, une sur cinquante est ignorée, afin qu’un épisode isolé ne décide pas du résultat. Le défilement de la page et le survol des éléments à la souris ne sont pas des interactions comptabilisées.
C’est un choix délibéré : l’utilisateur se souvient du bouton qui n’a pas répondu, pas des dix qui ont fonctionné. Pour améliorer l’INP, il faut donc trouver les interactions les plus lentes, pas seulement accélérer celles qui sont déjà rapides.
Pourquoi l’INP est une affaire de business
Les interactions lentes surviennent aux moments où l’utilisateur fait quelque chose d’important : choisir une taille, appliquer un filtre, ajouter un produit au panier, remplir un formulaire, ouvrir le menu pour chercher une rubrique. Une page qui ne répond pas génère des touchers répétés, des actions en double, des doutes sur ce qui s’est passé, et finalement un abandon sur le parcours même qui mène à la conversion. C’est aussi la métrique la plus liée à la perception de la qualité d’un site : une page lente à répondre semble cassée, même quand elle ne l’est pas.
Les causes les plus courantes
- Des tâches longues sur le thread principal. Les scripts qui exécutent des dizaines ou des centaines de millisecondes de travail sans interruption bloquent toute interaction qui arrive entre-temps.
- Les scripts tiers. Balises marketing, pixels publicitaires, chat, analytics et outils de tests A/B ajoutent un travail qui se concentre souvent au moment même où l’utilisateur commence à interagir.
- Des gestionnaires d’événements lourds. Un clic qui met à jour de nombreuses parties de la page, envoie des données de suivi, recalcule filtres et prix d’un seul coup, avant d’afficher la moindre réponse.
- Des pages coûteuses à réafficher. Un DOM de milliers d’éléments, des feuilles de style complexes, des lectures et écritures de mise en page alternées qui forcent le navigateur à recalculer plusieurs fois.
- Le JavaScript différé jusqu’au premier clic. Les techniques qui retardent tous les scripts jusqu’à la première interaction concentrent le travail exactement à ce moment, comme nous l’avons expliqué en parlant de retarder jusqu’au premier clic.
Comment l’améliorer
Le principe directeur est de laisser le thread principal libre de répondre. Le premier outil consiste à découper les tâches longues en morceaux plus petits, en rendant périodiquement la main au navigateur : le travail total reste le même, mais une interaction peut se glisser entre un morceau et le suivant au lieu d’attendre que tout soit terminé.
Le deuxième principe est d’afficher tout de suite une réponse et de différer le reste. Dans un gestionnaire de clic, il vaut mieux mettre à jour d’abord ce que voit l’utilisateur, comme l’état du bouton ou un indicateur de chargement, et n’exécuter qu’ensuite le travail non urgent, comme l’envoi des données de suivi :
// Rend la main au navigateur, avec une solution de repli là où scheduler.yield n’existe pas.
const yieldToMain = () =>
globalThis.scheduler?.yield?.() ?? new Promise( ( r ) => setTimeout( r, 0 ) );
button.addEventListener( 'click', async () => {
button.classList.add( 'is-loading' ); // réponse visible tout de suite
await yieldToMain(); // le navigateur affiche l’image
updateCart(); // travail nécessaire
await yieldToMain();
sendTracking(); // travail non urgent, en dernier
} );
- Réduire le JavaScript chargé sur chaque page, en supprimant les plugins et bibliothèques inutiles et en ne chargeant les composants que là où ils servent.
- Maîtriser les tiers : limiter leur nombre, les charger sans blocage et vérifier leur coût réel sur les interactions.
- Garder le DOM et la complexité des styles sous contrôle, et utiliser
content-visibilitypour les sections hors écran. - Éviter les recalculs de mise en page forcés, en regroupant les lectures de tailles avant les modifications.
- Sortir le travail lourd du thread principal, dans un web worker ou sur le serveur, quand il ne concerne pas directement l’interface.
Comment le mesurer
L’INP est par nature une métrique de terrain : il exige de vraies interactions, et un test de laboratoire qui se contente de charger la page n’en effectue aucune. C’est pourquoi Lighthouse ne rapporte pas l’INP et utilise le Total Blocking Time comme indicateur indirect du risque. Les valeurs réelles se lisent dans PageSpeed Insights et dans Search Console à partir des données CrUX, en se rappelant qu’elles se mettent à jour sur une fenêtre de 28 jours.
Pour le diagnostic, le panneau Performance de Chrome DevTools affiche en temps réel la latence des interactions que nous effectuons sur la page, et permet d’enregistrer une trace pour voir ce qui occupe le thread principal à ce moment-là. Sur le terrain, la bibliothèque web-vitals, dans sa version avec attribution, indique l’élément, le type d’interaction et la durée de chaque phase :
import { onINP } from 'web-vitals/attribution';
onINP( ( { value, attribution } ) => {
console.log( 'INP', Math.round( value ), 'ms', {
element: attribution.interactionTarget,
type: attribution.interactionType,
inputDelay: attribution.inputDelay,
processing: attribution.processingDuration,
presentation: attribution.presentationDelay,
} );
} );
Collecter ces données auprès d’utilisateurs réels, même sur une période limitée, est souvent le moyen le plus rapide de savoir quel bouton ou quel script est responsable : les interactions lentes se concentrent presque toujours sur quelques éléments et quelques pages.
En résumé
L’INP mesure le temps qui s’écoule entre une interaction de l’utilisateur et l’image qui en montre l’effet, sur l’ensemble des interactions de la visite, et rapporte l’une des pires. Il est bon en moins de 200 millisecondes au 75e percentile et se décompose en délai d’entrée, traitement et présentation. Les causes sont presque toujours un thread principal surchargé, des gestionnaires d’événements lourds et des pages coûteuses à réafficher.
L’améliorer revient surtout à faire moins de travail, et à le faire au bon moment : moins de JavaScript et moins de tiers, des tâches découpées, une réponse visible tout de suite et le travail non urgent différé. C’est l’optimisation que l’on ressent le plus à l’usage, parce qu’elle concerne le moment où l’utilisateur demande quelque chose au site et attend une réponse.