Optimiser l'interaction pour la page suivante

Découvrez comment optimiser l'Interaction to Next Paint de votre site Web.

Publié le 19 mai 2023, dernière mise à jour le 2 septembre 2025

L'Interaction to Next Paint (INP) est une métrique Core Web Vitals stable qui évalue la réactivité globale d'une page aux interactions des utilisateurs en observant la latence de toutes les interactions éligibles qui se produisent tout au long de la visite d'un utilisateur sur une page. La valeur INP finale correspond à l'interaction la plus longue observée (en ignorant parfois les anomalies).

Pour offrir une expérience utilisateur de qualité, les sites Web doivent s'efforcer d'avoir un Interaction to Next Paint de 200 millisecondes ou moins. Afin d'atteindre cet objectif pour la plupart de vos utilisateurs, un bon seuil à mesurer est le 75e centile de vos chargements de page, segmentés entre appareils mobiles et ordinateurs.

Les bonnes valeurs d'INP sont de 200 millisecondes ou moins, les mauvaises valeurs sont supérieures à 500 millisecondes, et les valeurs intermédiaires doivent être améliorées.
Seuils INP

Selon le site Web, il peut y avoir peu ou pas d'interactions (par exemple, des pages contenant principalement du texte et des images, avec peu ou pas d'éléments interactifs). Dans le cas de sites Web tels que des éditeurs de texte ou des jeux, il peut y avoir des centaines, voire des milliers d'interactions. Dans les deux cas, un INP élevé nuit à l'expérience utilisateur.

Améliorer l'INP demande du temps et des efforts, mais cela permet d'offrir une meilleure expérience utilisateur. Dans ce guide, nous allons explorer une méthode pour améliorer l'INP.

Déterminer la cause d'un mauvais INP

Avant de pouvoir corriger les interactions lentes, vous aurez besoin de données pour savoir si l'INP de votre site Web est faible ou doit être amélioré. Une fois que vous disposez de ces informations, vous pouvez passer à l'atelier pour commencer à diagnostiquer les interactions lentes et trouver une solution.

Rechercher les interactions lentes sur le terrain

Idéalement, votre parcours d'optimisation de l'INP commencera par les données de champ. Dans l'idéal, les données de terrain d'un fournisseur de surveillance des utilisateurs réels (RUM) vous fournissent non seulement la valeur INP d'une page, mais aussi des données contextuelles qui mettent en évidence l'interaction spécifique responsable de la valeur INP elle-même, si l'interaction s'est produite pendant ou après le chargement de page, le type d'interaction (clic, pression sur une touche ou appui) et d'autres informations utiles.

Si vous ne faites pas appel à un fournisseur de RUM pour obtenir des données réelles, le guide sur les données réelles de l'INP vous conseille d'utiliser PageSpeed Insights pour afficher les données du rapport sur l'expérience utilisateur de Chrome (CrUX) afin de combler les lacunes. CrUX est l'ensemble de données Google du programme Core Web Vitals. Il fournit un résumé général des métriques pour des millions de sites Web, y compris l'INP. Cependant, CrUX ne fournit souvent pas les données contextuelles que vous obtiendriez d'un fournisseur de RUM pour vous aider à analyser les problèmes. C'est pourquoi nous recommandons toujours aux sites d'utiliser un fournisseur de RUM lorsque cela est possible, ou d'implémenter leur propre solution de RUM pour compléter ce qui est disponible dans CrUX.

Diagnostiquer les interactions lentes en laboratoire

Idéalement, vous devriez commencer à effectuer des tests en laboratoire une fois que vous disposez de données de terrain suggérant que vos interactions sont lentes. En l'absence de données de terrain, il existe des stratégies pour identifier les interactions lentes en laboratoire. Ces stratégies incluent le suivi des parcours utilisateur courants et le test des interactions en cours de route, ainsi que l'interaction avec la page pendant le chargement (lorsque le thread principal est souvent le plus occupé) afin d'identifier les interactions lentes pendant cette partie cruciale de l'expérience utilisateur.

Optimiser les interactions

Une fois que vous avez identifié une interaction lente et que vous pouvez la reproduire manuellement dans l'atelier, l'étape suivante consiste à l'optimiser.

Les interactions peuvent être divisées en trois sous-parties :

  1. Le délai d'entrée, qui commence lorsque l'utilisateur lance une interaction avec la page et se termine lorsque les rappels d'événement pour l'interaction commencent à s'exécuter.
  2. La durée de traitement, qui correspond au temps nécessaire à l'exécution des rappels d'événements.
  3. Le délai de présentation, qui correspond au temps nécessaire au navigateur pour présenter le frame suivant contenant le résultat visuel de l'interaction.
Exemple d'interaction sur le thread principal. L'utilisateur effectue une saisie pendant l'exécution des tâches bloquantes. L'entrée est retardée jusqu'à ce que ces tâches soient terminées. Ensuite, les gestionnaires d'événements pointerup, mouseup et click sont exécutés, puis le rendu et la peinture sont lancés jusqu'à ce que l'image suivante soit présentée.
Cycle de vie d'une interaction. Un délai d'entrée se produit jusqu'à ce que les gestionnaires d'événements commencent à s'exécuter, ce qui peut être dû à des facteurs tels que des tâches longues sur le thread principal. Les rappels du gestionnaire d'événements de l'interaction sont ensuite exécutés, et un délai se produit avant la présentation de l'image suivante.

La somme de ces trois sous-parties correspond à la latence totale de l'interaction. Chaque sous-partie d'une interaction contribue à la latence totale de l'interaction. Il est donc important de savoir comment optimiser chaque partie de l'interaction pour qu'elle s'exécute le plus rapidement possible.

Identifier et réduire le délai de réponse à l'entrée

Lorsqu'un utilisateur interagit avec une page, la première partie de cette interaction est le délai d'entrée. En fonction des autres activités sur la page, les délais d'entrée peuvent être considérables. Cela peut être dû à une activité sur le thread principal (peut-être en raison du chargement, de l'analyse et de la compilation de scripts), à la gestion des extractions, aux fonctions de minuteur ou même à d'autres interactions qui se produisent rapidement et se chevauchent.

Quelle que soit la source du délai d'entrée d'une interaction, vous devez le réduire au minimum afin que les interactions puissent commencer à exécuter les rappels d'événements dès que possible.

Relation entre l'évaluation des scripts et les tâches longues au démarrage

L'interactivité lors du démarrage est un aspect essentiel du cycle de vie de la page. Lorsqu'une page se charge, elle s'affiche initialement, mais il est important de se rappeler que ce n'est pas parce qu'une page s'est affichée qu'elle a fini de charger. Selon le nombre de ressources dont une page a besoin pour devenir entièrement fonctionnelle, il est possible que les utilisateurs tentent d'interagir avec la page pendant qu'elle est encore en cours de chargement.

L'évaluation du script peut prolonger le délai d'entrée d'une interaction pendant le chargement d'une page. Une fois qu'un fichier JavaScript a été récupéré sur le réseau, le navigateur doit encore effectuer des opérations avant de pouvoir l'exécuter. Ces opérations incluent l'analyse d'un script pour vérifier que sa syntaxe est valide, sa compilation en bytecode, puis son exécution.

Selon la taille d'un script, cette tâche peut introduire des tâches longues sur le thread principal, ce qui retardera la réponse du navigateur aux autres interactions utilisateur. Pour que votre page reste réactive aux entrées utilisateur pendant le chargement, il est important de comprendre ce que vous pouvez faire pour réduire la probabilité de tâches longues pendant le chargement de la page, afin que celle-ci reste réactive.

Optimiser les rappels d'événements

Le délai d'entrée n'est que la première partie de ce que mesure l'INP. Vous devez également vous assurer que les rappels d'événements qui s'exécutent en réponse à une interaction utilisateur peuvent se terminer le plus rapidement possible.

Céder souvent la place au thread principal

Le meilleur conseil général pour optimiser les rappels d'événements est d'y effectuer le moins d'opérations possible. Cependant, votre logique d'interaction peut être complexe, et vous ne pourrez peut-être réduire que marginalement le travail qu'elles effectuent.

Si vous constatez que c'est le cas pour votre site Web, vous pouvez essayer de diviser le travail dans les rappels d'événements en tâches distinctes. Cela évite que le travail collectif ne devienne une tâche longue qui bloque le thread principal, ce qui permet à d'autres interactions qui, autrement, attendraient sur le thread principal de s'exécuter plus tôt.

setTimeout est un moyen de diviser les tâches, car le rappel qui lui est transmis s'exécute dans une nouvelle tâche. Vous pouvez utiliser setTimeout seul ou l'abstraire dans une fonction distincte pour une exécution plus ergonomique.

Il est préférable de céder le contrôle de manière indiscriminée plutôt que de ne pas le céder du tout. Cependant, il existe une manière plus nuancée de céder le contrôle au thread principal, qui consiste à ne le céder qu'immédiatement après un rappel d'événement qui met à jour l'interface utilisateur, afin que la logique de rendu puisse s'exécuter plus tôt.

Céder pour permettre au travail de rendu de se produire plus tôt

Une technique de rendement plus avancée consiste à structurer le code dans vos rappels d'événements afin de limiter l'exécution à la logique requise pour appliquer les mises à jour visuelles de l'image suivante. Tout le reste peut être reporté à une tâche ultérieure. Cela permet non seulement de garder les rappels légers et agiles, mais aussi d'améliorer le délai d'affichage des interactions en empêchant les mises à jour visuelles de bloquer le code de rappel d'événement.

Par exemple, imaginez un éditeur de texte enrichi qui met en forme le texte au fur et à mesure que vous tapez, mais qui met également à jour d'autres aspects de l'interface utilisateur en réponse à ce que vous avez écrit (comme le nombre de mots, la mise en évidence des fautes d'orthographe et d'autres commentaires visuels importants). De plus, l'application peut avoir besoin d'enregistrer ce que vous avez écrit pour que vous ne perdiez pas votre travail si vous quittez l'application et y revenez.

Dans cet exemple, les quatre actions suivantes doivent se produire en réponse aux caractères saisis par l'utilisateur. Toutefois, seul le premier élément doit être effectué avant que l'image suivante ne soit présentée.

  1. Mettez à jour la zone de texte avec ce que l'utilisateur a saisi et appliquez la mise en forme requise.
  2. Mettre à jour la partie de l'UI qui affiche le nombre de mots actuel.
  3. Exécutez la logique pour vérifier les fautes d'orthographe.
  4. Enregistrez les modifications les plus récentes (localement ou dans une base de données distante).

Le code permettant d'effectuer cette opération peut se présenter comme suit :

textBox.addEventListener('input', (inputEvent) => {
  // Update the UI immediately, so the changes the user made
  // are visible as soon as the next frame is presented.
  updateTextBox(inputEvent);

  // Use `setTimeout` to defer all other work until at least the next
  // frame by queuing a task in a `requestAnimationFrame()` callback.
  requestAnimationFrame(() => {
    setTimeout(() => {
      const text = textBox.textContent;
      updateWordCount(text);
      checkSpelling(text);
      saveChanges(text);
    }, 0);
  });
});

La visualisation suivante montre comment le report des mises à jour non critiques après l'image suivante peut réduire la durée de traitement et, par conséquent, la latence globale de l'interaction.

Représentation d'une interaction au clavier et des tâches suivantes dans deux scénarios. Dans la figure du haut, la tâche essentielle au rendu et toutes les tâches d'arrière-plan suivantes s'exécutent de manière synchrone jusqu'à ce que l'opportunité de présenter une image se présente. Dans la figure du bas, la tâche essentielle au rendu s'exécute en premier, puis cède la place au thread principal pour présenter un nouveau frame plus tôt. Les tâches en arrière-plan s'exécutent ensuite.
Cliquez sur l'image pour l'afficher en haute résolution.

Bien que l'utilisation de setTimeout() dans un appel requestAnimationFrame() dans l'exemple de code précédent soit un peu ésotérique, il s'agit d'une méthode efficace qui fonctionne dans tous les navigateurs pour empêcher le code non critique de bloquer l'image suivante.

Éviter le thrashing de mise en page

Le thrashing de mise en page (parfois appelé "mise en page synchrone forcée") est un problème de performances de rendu où la mise en page se produit de manière synchrone. Il se produit lorsque vous mettez à jour des styles en JavaScript, puis que vous les lisez dans la même tâche. De nombreuses propriétés en JavaScript peuvent provoquer un thrashing de mise en page.

Visualisation du thrashing de mise en page, comme indiqué dans le panneau "Performances" des outils pour les développeurs Chrome.
Exemple de dégradation de la mise en page, comme illustré dans le panneau "Performances" des outils pour les développeurs Chrome. Les tâches de rendu qui impliquent un thrashing de mise en page sont signalées par un triangle rouge dans l'angle supérieur droit de la partie de la pile d'appel, souvent intitulée Recalculate Style (Recalculer le style) ou Layout (Mise en page).

Le thrashing de mise en page est un goulot d'étranglement des performances, car en mettant à jour les styles, puis en demandant immédiatement les valeurs de ces styles en JavaScript, le navigateur est obligé d'effectuer un travail de mise en page synchrone qu'il aurait pu attendre d'effectuer de manière asynchrone plus tard, une fois l'exécution des rappels d'événements terminée.

Réduire le délai de présentation

Le délai de présentation d'une interaction s'étend de la fin de l'exécution des rappels d'événements d'une interaction jusqu'au moment où le navigateur est en mesure d'afficher le frame suivant qui montre les modifications visuelles qui en résultent.

Réduire la taille du DOM

Lorsque le DOM d'une page est petit, le rendu se termine généralement rapidement. Toutefois, lorsque les DOM deviennent très volumineux, le travail de rendu a tendance à augmenter avec la taille du DOM. La relation entre le travail de rendu et la taille du DOM n'est pas linéaire, mais les DOM volumineux nécessitent plus de travail de rendu que les DOM de petite taille. Un DOM volumineux est problématique dans deux cas :

  1. Lors du rendu initial de la page, lorsqu'un DOM volumineux nécessite beaucoup de travail pour afficher l'état initial de la page.
  2. En réponse à une interaction utilisateur, où un DOM volumineux peut rendre les mises à jour de rendu très coûteuses et donc augmenter le temps nécessaire au navigateur pour présenter l'image suivante.

N'oubliez pas qu'il existe des cas où les DOM volumineux ne peuvent pas être réduits de manière significative. Bien qu'il existe des approches pour réduire la taille du DOM, comme l'aplatissement du DOM ou l'ajout au DOM lors des interactions utilisateur pour que la taille initiale du DOM reste faible, ces techniques ne sont pas toujours suffisantes.

Utiliser content-visibility pour afficher les éléments hors écran de manière différée

Pour limiter la quantité de travail de rendu lors du chargement de page et en réponse aux interactions de l'utilisateur, vous pouvez vous appuyer sur la propriété CSS content-visibility, qui revient à effectuer un rendu différé des éléments à mesure qu'ils s'approchent de la fenêtre d'affichage. Bien que l'utilisation efficace de content-visibility puisse nécessiter un peu de pratique, il est intéressant de l'étudier si le résultat est un délai d'affichage plus court, ce qui peut améliorer l'INP de votre page.

Tenez compte des coûts de performances lors de l'affichage du code HTML à l'aide de JavaScript

Qui dit HTML dit analyse HTML. Une fois que le navigateur a fini d'analyser le code HTML dans un DOM, il doit lui appliquer des styles, effectuer des calculs de mise en page, puis afficher cette mise en page. Il s'agit d'un coût inévitable, mais la façon dont vous effectuez le rendu HTML est importante.

Lorsque le serveur envoie du code HTML, il arrive dans le navigateur sous forme de flux. Le streaming signifie que la réponse HTML du serveur arrive par fragments. Le navigateur optimise la façon dont il gère un flux en analysant progressivement les fragments de ce flux à mesure qu'ils arrivent et en les affichant petit à petit. Il s'agit d'une optimisation des performances, car le navigateur génère implicitement des résultats de manière périodique et automatique lors du chargement de page, et vous en bénéficiez sans frais.

La première visite d'un site Web implique toujours une certaine quantité de code HTML. Une approche courante consiste à commencer par un code HTML initial minimal, puis à utiliser JavaScript pour remplir la zone de contenu. Les mises à jour ultérieures de cette zone de contenu se produisent également à la suite d'interactions de l'utilisateur. C'est ce qu'on appelle généralement le modèle d'application monopage. L'un des inconvénients de ce modèle est que, en affichant le code HTML avec JavaScript sur le client, vous devez non seulement payer le coût du traitement JavaScript pour créer ce code HTML, mais le navigateur ne s'arrêtera pas tant qu'il n'aura pas fini d'analyser ce code HTML et de l'afficher.

Toutefois, il est essentiel de se rappeler que même les sites Web qui ne sont pas des applications monopages impliquent probablement un certain rendu HTML via JavaScript à la suite d'interactions. En général, cela ne pose pas de problème, tant que vous n'affichez pas de grandes quantités de code HTML sur le client, ce qui peut retarder la présentation de l'image suivante. Toutefois, il est important de comprendre les implications de cette approche sur les performances du rendu HTML dans le navigateur, et comment elle peut impacter la réactivité de votre site Web aux entrées utilisateur si vous affichez beaucoup de code HTML à l'aide de JavaScript.

Conclusion

L'amélioration de l'INP de votre site est un processus itératif. Lorsque vous corrigez une interaction lente sur le terrain, il est fort probable que vous commenciez à trouver d'autres interactions lentes, en particulier si votre site Web offre beaucoup d'interactivité, et que vous deviez également les optimiser.

La clé pour améliorer l'INP est la persévérance. Avec le temps, vous pourrez améliorer la réactivité de votre page pour que les utilisateurs soient satisfaits de l'expérience que vous leur proposez. Il est également fort probable que, lorsque vous développerez de nouvelles fonctionnalités pour vos utilisateurs, vous devrez suivre le même processus pour optimiser les interactions qui leur sont spécifiques. Cela demandera du temps et des efforts, mais cela en vaudra la peine.