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 9 septembre 2025

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

Pour offrir une expérience utilisateur de qualité, les sites Web doivent s'efforcer de ne pas dépasser un INP de 200 millisecondes. Pour atteindre cet objectif pour la plupart de vos utilisateurs, un bon seuil à mesurer est le 75e centile des chargements de page, segmenté sur les appareils mobiles et les ordinateurs.

Les valeurs INP sont considérées comme bonnes si elles sont inférieures ou égales à 200 millisecondes, mauvaises si elles sont supérieures à 500 millisecondes et nécessitent une amélioration si elles se situent entre les deux.
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, une latence d'interaction élevée risque de nuire à l'expérience utilisateur.

Améliorer l'INP demande du temps et des efforts, mais cela permet d'améliorer l'expérience utilisateur. Ce guide vous explique comment améliorer l'INP.

Identifier les causes d'une mauvaise INP

Avant de pouvoir corriger les interactions lentes, vous aurez besoin de données pour déterminer 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.

Identifier les interactions lentes sur le terrain

Idéalement, votre parcours d'optimisation de l'INP commencera par les données de terrain. Dans le meilleur des cas, les données de champ d'un fournisseur de Real User Monitoring (RUM) vous fourniront 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 la 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 RUM pour obtenir des données réelles, le guide sur les données réelles concernant l'INP vous conseille d'utiliser PageSpeed Insights pour afficher les données du rapport d'expérience utilisateur Chrome (CrUX) afin de combler les lacunes. CrUX est l'ensemble de données officiel 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. Toutefois, CrUX ne fournit souvent pas les données contextuelles que vous obtiendriez d'un fournisseur RUM pour vous aider à analyser les problèmes. C'est pourquoi nous recommandons toujours aux sites d'utiliser un fournisseur RUM lorsque cela est possible, ou d'implémenter leur propre solution RUM pour compléter ce qui est disponible dans CrUX.

Diagnostiquer les interactions lentes dans le laboratoire

Idéalement, vous devriez commencer à effectuer des tests en laboratoire une fois que vous disposez de données de terrain suggérant que vous avez des interactions lentes. En l'absence de données de champ, 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 en laboratoire, 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 prochain frame contenant le résultat visuel de l'interaction.
Exemple d'interaction sur le thread principal. L'utilisateur saisit une entrée pendant l'exécution de tâches bloquantes. L'entrée est retardée jusqu'à ce que ces tâches soient terminées, après quoi les gestionnaires d'événements pointerup, mouseup et click s'exécutent, puis le rendu et la peinture sont lancés jusqu'à ce que la prochaine frame 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 s'exécutent ensuite, et un délai se produit avant la présentation du frame suivant.

La somme de ces trois sous-parties correspond à la latence d'interaction totale. 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 moins longtemps 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 de saisie 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énement dès que possible.

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

Un aspect essentiel de l'interactivité dans le cycle de vie d'une page se produit au démarrage. Lorsqu'une page se charge, elle s'affiche initialement. Toutefois, il est important de se rappeler que ce n'est pas parce qu'une page a été affichée qu'elle a fini de se 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 de 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 tâches avant de pouvoir l'exécuter. Il s'agit, entre autres, d'analyser un script pour vérifier que sa syntaxe est valide, de le compiler en bytecode et, enfin, de l'exécuter.

En fonction de la taille d'un script, ce travail peut introduire des tâches longues sur le thread principal, ce qui empêchera le navigateur de répondre à d'autres interactions de l'utilisateur. Pour que votre page reste réactive aux saisies de l'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 qu'elle reste rapide.

Optimiser les rappels d'événements

Le temps First Input Delay n'est que la première partie de ce que mesure l'INP. Vous devrez également vous assurer que les rappels d'événement 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 de travail possible. Toutefois, votre logique d'interaction peut être complexe, et vous ne pourrez peut-être réduire que de manière marginale le travail qu'ils effectuent.

Si c'est le cas pour votre site Web, vous pouvez essayer de répartir le travail dans les rappels d'événements en tâches distinctes. Cela empêche le travail collectif de devenir une tâche longue qui bloque le thread principal, ce qui permet à d'autres interactions qui seraient autrement en attente sur le thread principal de s'exécuter plus tôt.

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

Il est préférable de céder la place sans discrimination plutôt que de ne pas le faire du tout. Toutefois, il existe une façon plus nuancée de céder la place au thread principal. Il s'agit de ne céder la place 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 la main pour permettre au rendu de se produire plus tôt

Une technique de génération plus avancée consiste à structurer le code dans vos rappels d'événements pour limiter l'exécution à la logique requise pour appliquer les mises à jour visuelles du prochain frame. 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 temps de rendu 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 à mesure que vous le saisissez, mais qui met également à jour d'autres aspects de l'UI en fonction de ce que vous avez écrit (comme le nombre de mots, la mise en évidence des fautes d'orthographe et d'autres informations visuelles importantes). De plus, l'application peut également avoir besoin d'enregistrer ce que vous avez écrit afin que vous ne perdiez pas votre travail si vous quittez l'application et y revenez.

Dans cet exemple, les quatre éléments suivants doivent se produire en réponse aux caractères saisis par l'utilisateur. Toutefois, seul le premier élément doit être effectué avant l'affichage de la frame suivante.

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

Le code 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 jusqu'à la prochaine frame peut réduire la durée de traitement et donc la latence globale de l'interaction.

Représentation d'une interaction au clavier et des tâches qui en découlent dans deux scénarios. Dans la figure du haut, la tâche essentielle au rendu et toutes les tâches en arrière-plan suivantes s'exécutent de manière synchrone jusqu'à ce qu'une opportunité de présenter un frame se présente. Dans la figure du bas, le travail essentiel au rendu s'exécute en premier, puis cède la place au thread principal pour présenter un nouveau frame plus rapidement. Les tâches en arrière-plan sont ensuite exécutées.
Cliquez sur l'image pour afficher une version 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 le frame suivant.

É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. Cela 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 entraîner un thrashing de mise en page.

Visualisation du thrashing de mise en page dans le panneau "Performances" des outils pour les développeurs Chrome.
Exemple de thrashing de mise en page, tel qu'il apparaît dans le panneau "Performances" des outils pour les développeurs Chrome. Les tâches de rendu impliquant un thrashing de mise en page sont indiquées par un triangle rouge en haut à droite de la partie de la pile d'appel, souvent intitulée Recalculer le style ou 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 pour effectuer de manière asynchrone plus tard, une fois les rappels d'événements terminés.

Minimiser le délai de présentation

Le délai de présentation d'une interaction marque les intervalles entre la fin de l'exécution des rappels d'événement d'une interaction et le moment où le navigateur est en mesure de peindre le frame suivant qui montre les modifications visuelles résultantes.

Minimiser 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 rendu a tendance à évoluer en fonction de la taille du DOM. La relation entre le rendu et la taille du DOM n'est pas linéaire, mais les grands DOM nécessitent plus de travail de rendu que les petits DOM. Un DOM volumineux est problématique dans deux cas :

  1. Lors du rendu initial de la page, où 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 grand DOM peut rendre les mises à jour de rendu très coûteuses et, par conséquent, augmenter le temps nécessaire au navigateur pour présenter le prochain frame.

N'oubliez pas que dans certains cas, il est impossible de réduire considérablement les grands DOM. Il existe des approches que vous pouvez adopter pour réduire la taille du DOM, comme aplatir votre DOM ou ajouter au DOM lors des interactions utilisateur pour maintenir une petite taille de DOM initiale. Toutefois, ces techniques peuvent avoir leurs limites.

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 la page et en réponse aux interactions utilisateur, vous pouvez vous appuyer sur la propriété CSS content-visibility, qui équivaut à un rendu différé des éléments à mesure qu'ils approchent de la fenêtre d'affichage. Bien que l'utilisation efficace de content-visibility puisse nécessiter un peu de pratique, il vaut la peine d'étudier si le résultat est un temps de rendu plus faible qui peut améliorer l'INP de votre page.

Tenez compte des coûts de performances lorsque vous affichez du code HTML à l'aide de JavaScript.

Là où il y a du HTML, il y a de l'analyse HTML. Une fois que le navigateur a terminé d'analyser le HTML en 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 affichez le code 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 blocs. Le navigateur optimise la façon dont il gère un flux en analysant de manière incrémentielle les blocs de ce flux à mesure qu'ils arrivent, et en les affichant petit à petit. Il s'agit d'une optimisation des performances, car le navigateur cède implicitement la main de manière périodique et automatique lors du chargement de la page, et vous l'obtenez sans frais.

Bien que la première visite sur un site Web implique toujours une certaine quantité de code HTML, une approche courante consiste à commencer par un minimum de code HTML initial, 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 utilisateur. C'est ce que l'on appelle généralement le modèle d'application monopage (SPA). L'un des inconvénients de ce modèle est que, en affichant du code HTML avec JavaScript sur le client, vous obtenez non seulement le coût du traitement JavaScript pour créer ce code HTML, mais aussi le navigateur ne cède pas tant qu'il n'a pas terminé d'analyser ce code HTML et de l'afficher.

Toutefois, il est important de se rappeler que même les sites Web qui ne sont pas des SPA impliquent probablement un certain rendu HTML via JavaScript à la suite d'interactions. En général, cela ne pose pas de problème, à condition de ne pas afficher de grandes quantités de code HTML sur le client, ce qui peut retarder la présentation de la prochaine frame. Toutefois, il est important de comprendre les implications de cette approche en termes de performances pour le rendu HTML dans le navigateur, et comment elle peut impacter la réactivité de votre site Web aux saisies utilisateur si vous effectuez le rendu de 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 y a de fortes chances que vous trouviez d'autres interactions lentes, surtout si votre site Web offre beaucoup d'interactivité. Vous devrez également les optimiser.

La clé pour améliorer l'INP est la persévérance. Au fil du temps, vous pourrez rendre votre page suffisamment réactive pour que les utilisateurs soient satisfaits de l'expérience que vous leur proposez. Il est également 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 vaut la peine.

Image de bannière provenant d'Unsplash, par David Pisnoy et modifiée conformément à la licence Unsplash.