Vous avez découvert que l’INP est devenu officiellement d’une des principales metrics des Core Web Vitals, et donc, potentiellement un critère de référencement Google ? Vous désirez apprendre comment optimiser votre site pour obtenir un excellent score INP ?

Dans ce cas, ne manquez pas ci-dessous notre guide ultime de l’optimisation de l’Interaction to Next Paint !

Si par le passé, vous avez suivi les conseils de Google pour améliorer le FID ou plus globalement, les Core Web Vitals, bravo ! Vous avez déjà commencé à optimiser l’aspect « réactivité » de votre site.

Les améliorations apportées au FID constituent déjà une bonne base pour vous assurer d’avoir un bon INP, et donc, une bonne “réactivité” de vos pages. Mais cela ne fait pas tout. La barre est plus haute avec INP, car il s’agit bien d’une metric différente et plus avancée.

L’INP va plus loin que le FID.

La metric « Interaction to Next Paint » peut prendre du temps à être maîtrisée, et c’est tout à fait normal. Mais le jeu en vaut la chandelle, car corriger un problème d’INP offrira une bien meilleure expérience à vos utilisateurs.

Pour vous aider à vous concentrer sur les optimisations offrant le meilleur retour sur investissement, nous avons collecté nos recommandations les plus efficaces pour améliorer les Core Web Vitals, le FID et l’INP.

Les recommandations à suivre en priorité consistent notamment à…

  • éviter le JavaScript inutile
  • éviter ou diviser les tâches JavaScript longues à charger
  • éviter les trop gros changements de “rendu” suite aux interactions de l’utilisateur avec la page

En effet, globalement, un site sans interactions JavaScript (donc HTML et CSS purs) devrait avoir un INP parfait puisque les changements de rendus suite aux interactions sont généralement mis en place grâce au JavaScript (sauf rares exceptions depuis le CSS3, les transitions et pseudo-classes comme :target par exemple).

Ci-dessous, nous détaillons des solutions accessibles aux créateurs de sites de tout niveau (débutant, intermédiaire et expert). Cependant, avant de chercher à mettre en place ces solutions, assurez-vous d’avoir bien compris Qu’est-ce que l’INP (Interaction to Next Paint) et comment ça marche ?

Tout de suite après cette lecture, rendez-vous ci-dessous pour résoudre vos problèmes d’INP 😉

Qu’est-ce que l’INP ? (version courte)

Pour résumer très brièvement, l’INP se charge de mesurer tous les délais nécessaires pour exécuter les actions à réaliser suite aux interactions des utilisateurs avec les éléments de vos pages Web, comme les boutons HTML, les champs textes ou tout autre élément interactif de vos pages.

L’objectif de l’INP dans les Core Web Vitals est d’encourager les créateurs de sites de réduire le temps écoulé entre le moment où un utilisateur initie une interaction sur le site, et celui où la “frame” suivante est affichée, et ce, pour toutes ou la plupart des interactions initiées par les utilisateurs sur les pages.

Cette vidéo illustre un exemple de mauvaise “réactivité” suite à une interaction (donc un mauvais INP), comparée à une bonne réactivité. À gauche, des “long tasks” empêchent l’ouverture de l’accordéon. Cela amène l’utilisateur à cliquer plusieurs fois, pensant que l’expérience est défaillante. Il y a donc un problème d’ergonomie. Lorsque le “main thread” reprend la main, il traite les tâches qui étaient restées en attente, ce qui a pour effet d’ouvrir et de fermer l’accordéon. À l’inverse, sur la droite, on peut voir une page plus réactive qui ouvre l’accordéon rapidement et sans problème d’ergonomie.

Solutions simples pour résoudre les problèmes d’INP sous WordPress ou PrestaShop (niveau débutant)

Déterminez vous-même si EasyHoster est le meilleur hébergeur Web pour l'hébergement de votre site WordPress ou autre ! (vidéo)

Si vous n’êtes pas développeur, que vous utilisez WordPress ou PrestaShop et que vous avez un mauvais INP, voici une méthode simple pour trouver le coupable…

Il vous suffit de désactiver temporairement tous les plugins ou modules que vous avez installé sur votre site.

Ensuite, faites des tests d’interaction depuis une fenêtre privée Google Chrome sur les éléments qui semblaient être concernés par les problèmes d’INP, tout en activant la capture des Performances ↓ depuis les Outils pour développeurs de Google Chrome.

Si le problème d’INP n’est pas résolu suite à la désactivation de tous les plugins, celui-ci peut être causé par votre thème WordPress ou template PrestaShop. Dans ce cas, tentez de repasser temporairement sur le template de base de votre CMS (thème par défaut). Si cela a résolu le problème d’INP, vous avez trouvé le coupable. C’est probablement votre thème, dont la configuration ou le code devront être corrigés.

Sinon, revenez sur votre thème personnel et réactivez un à un chaque plugin WordPress ou module PrestaShop ayant un impact sur le frontend de votre site. Faites des tests manuels, sur PageSpeed Insights et/ou via les autres outils proposés ci-dessous ↓) à chaque fois qu’un plugin est réactivé, jusqu’au moment où réapparaissent les problèmes d’INP, de TBT, et les autres avertissements signalés, par exemple, par PageSpeed Insights (comme illustré ci-dessous).

minimize work during key interaction inp pagespeed

En procédant comme ceci, vous devriez voir assez clairement quel plugin ou module créé de l’INP sur votre site.

Vous pourrez donc prendre les décisions qui s’imposent :

  • changer de plugin par une alternative similaire
  • corriger la configuration du plugin problématique
  • contacter le développeur du plugin pour lui signaler le souci, etc.
Hébergement Web haut performance avec code promo EasyHoster : BIENVENUE15
Hébergement Web haut performance

Vous n’avez pas le temps de vous occuper vous-même de l’optimisation de votre INP ?

Saviez-vous qu’en plus de vous offrir des solutions d’hébergement haute performance, les équipes d’EasyHoster peuvent aussi vous proposer des Packs d’intervention pouvant être utilisés pour l’optimisation des scores Core Web Vitals.

Trouver un prestataire freelance WordPress WooCommerce, etc.

N’hésitez pas à contacter notre support technique pour en savoir plus !

Solutions avancées pour détecter et corriger les problèmes d’INP sans développement Web (niveau intermédiaire)

Si votre site web est éligible pour être inclus dans le « Chrome User Experience Report » (CrUX), vous pouvez rapidement obtenir des données INP de terrain à travers le CrUX de « PageSpeed Insights », à côté des données des autres metrics « Core Web Vitals », comme illustré ci-dessous.

INP in pagespeed insights
L’INP de ce site étant supérieur à 200 ms, celui-ci devrait être amélioré.

Bien sûr, pour obtenir un bon INP, il faudra commencer par poser les bases, comme celles que vous posiez pour optimiser votre FID.

Par exemple, vous allez devoir priorisez les ressources critiques avec rel="preload" pour les ressources essentielles, surtout pour les scripts et feuilles de style cruciaux pour l’interactivité. De même, il convient d’utiliser les attributs "async" ou "defer" sur les balises de script pour contrôler le timing de l’exécution du JavaScript et éviter de bloquer la construction du DOM.

Si vous utilisez WordPress, rassurez-vous, ce type d’optimisations est réalisé automatiquement grâce à des plugins de performance complets tels que AccelerateWP ou WP Rocket.

Dans les rapports PageSpeed, afin de réduire l’INP vous pouvez commencer par vous concentrer sur ces 2 metrics : « Total Blocking Time ou TBT » et « Time To Interactive ou TTI ».

Ci-dessous, lisez attentivement cette capture d’écran qui reprend déjà une bonne partie des avertissements que vous devriez corriger pour optimiser le TBT :

Total Blocking Time TBT pagespeed

Comment on peut le voir en affichant la « Calculatrice PageSpeed ➚ » (voir le lien « Affichez la calculatrice » en dessous du score de Performance), le TBT y est pour beaucoup dans la dégradation de notre score (30%), et son optimisation devrait avoir un effet considérable sur l’INP.

TBT calculatrice pagespeed

En complément, puisqu’une image vaut mille mots, cette illustration vous permettra de facilement comprendre ce qu’est le TTI :

TTI time to interactive pagespeed
Time to Interactive : à 5,0s, l’utilisateur pense pouvoir interagir avec la page, mais c’est seulement à 5,5s qu’il peut réellement interagir, car des tâches JavaScript bloquantes sont toujours en cours en arrière-plan.

Bien sûr, faites en sorte de passer tous les avertissements (“Opportunités PageSpeed”) au vert, ne fut-ce que pour être au top sur toutes les metrics des Core Web Vitals… plusieurs peuvent concerner l’INP !

pagespeed minimize work during key interaction

Pour aller plus loin, puisque le rapport de PageSpeed n’offre pas énormément de détails pour vous aider à comprendre pleinement quelle est la source du problème d’INP, il sera parfois nécessaire de se retrousser les manches et de mettre un peu les mains dans le cambouis pour débusquer les sources d’interactions lentes.
Il s’agira de pouvoir attribuer les problèmes d’INP à des interactions individuelles précises en simulant manuellement des actions sur les interfaces de vos pages, tout en observant les données analysées par les Outils pour développeurs de Google Chrome > Performance (enregistrement) > Interactions (voir le point suivant).

Comment mesurer l’INP via les informations d’interactions des outils pour développeurs de Google Chrome ?

Vous pouvez utiliser l’onglet « Performance » des « Chrome Dev Tools » pour vous aider à mesurer l’INP :

  1. Ouvrez les « Outils pour les développeurs » de Google Chrome (clic droit sur la page > Inspecter)
  2. Ouvrez l’onglet « Performance » et dans les paramètres (icône d’écrou en haut à droite), envisagez d’activer un « CPU Throttling » de 4x ou 6x pour émuler un dispositif moins rapide
  3. Démarrez un nouvel enregistrement en cliquant sur le bouton d’enregistrement (cercle ◉ en haut à gauche)
  4. Interagissez avec la page, par exemple en cliquant sur des boutons, en tapant dans des champ de texte, etc. — N.B. : le survol d’éléments, le défilement ou le redimensionnant de la fenêtre ne sont pas comptabilisés par l’INP.
  5. Lorsque vous avez terminé, cliquez sur le bouton « Stop » et attendez que l’enregistrement soit analysé par Google Chrome

Une fois l’enregistrement terminé, Chrome affichera de très nombreuses données, avec des screenshots illustrant votre parcours complet sur la page. Ne vous inquiétez pas, vous pouvez ignorer la plupart des données affichées.
Nous allons nous concentrer sur celles utiles pour détecter les problèmes d’INP.

Donc, trouvez et développez la ligne « Interactions » puis survolez l’interaction qui vous intéresse, comme illustré ci-dessous.

Chrome Dev Tools Performance Interactions

Si vous avez une longue interaction qui dépasse 200 millisecondes, vous trouverez une zone avec une fine ligne rouge indiquant au survol la durée de l’interaction (Processing Time, etc).
Quand le seuil de 200 millisecondes est dépassé, Chrome affichera un avertissement disant « Long interaction is indicating poor page responsiveness », comme illustré ci-dessous.

Long interaction is indicating poor page responsiveness
Lors de ce test, le bouton destiné à accepter l’enregistrement de « cookies » créée une grande quantité d’INP… plus de 500ms !

Vous voyez la durée de l’interaction ainsi que le type d’interaction aligné à la capture d’écran qui vous permettra de savoir quel élément doit être optimisé.

Qu’est-ce qui cause un INP lent ?

Pensez au temps de traitement CPU nécessaire pour effectuer le rendu suite à certaines interactions. Un délai qui peut empêcher le navigateur d’afficher rapidement du contenu dynamique sur la page… c’est cela qui cause un INP lent.

Ce temps d’attente se décompose en 3 metrics / 3 composantes qui additionnées représentent votre score total d’INP : Input Delay, Processing Time, Presensation Delay.

Input Delay Processing Time Presentation Delay

Les détails de la metric INP en 3 composantes peut être retrouvé sous l’onglet Performance > Interactions des Outils pour développeurs de Google, comme nous l’avons vu précédemment.

  • Un « input delay » élevé indique qu’une activité en arrière-plan sur la page empêche le traitement de l’interaction de la page — L’Input Delay (délai d’entrée) fait référence au temps écoulé entre le moment où un utilisateur commence à interagir avec la page et le moment où les actions associées ou les “event callbacks” commencent à s’exécuter. Cela inclut les retards physiques ou techniques causés par le périphérique d’entrée (par exemple, le clavier, la souris, l’écran tactile) et les mécanismes de traitement des entrées du système.
  • Un « processing time » élevé signifie que les gestionnaires d’événements pour l’interaction prennent beaucoup de temps à s’exécuter — Une fois que l’entrée de l’utilisateur est reçue, le système doit la traiter pour déterminer la réponse ou l’action appropriée. Le Processing Time (temps de traitement) fait référence à la durée nécessaire pour que le système analyse et interprète les données d’entrée, effectue les calculs ou opérations nécessaires, et génère une sortie en réponse.
  • Un « presentation delay » élevé indique que le styling, la mise en page et l’affichage de l’interface utilisateur mise à jour retardent la prochaine impression — Après que le système ait généré la réponse en sortie, il y a généralement un délai avant qu’elle ne soit présentée à l’utilisateur. Le Presentation Delay (délai de présentation) englobe le temps nécessaire au système pour mettre à jour l’affichage, afficher les graphiques de l’interface utilisateur, et livrer la sortie à l’interface utilisateur ou au périphérique de sortie.

La somme de ces 3 composantes représente l’INP total :

Interaction to next paint components Input Delay Processing Time Presentation Delay

Pour en savoir plus, n’hésitez pas à consulter cet autre article sur l’INP.

Solutions avancées pour développeurs Web pour résoudre les problèmes d’INP (niveau expert)

La documentation suivante s’adresse plus particulièrement aux développeurs ayant une expertise solide en JavaScript.

Votre tâche consistera à diagnostiquer les problèmes ralentissant l’INP, comme des tâches JavaScript longues, trop d’activité sur le « main thread« , ou un DOM trop volumineux. Cela peut impliquer de rationaliser le JavaScript, de réduire le délai d’entrée (input delay), de simplifier la structure du DOM, ou de revoir les sélecteurs CSS utilisés.

Tout ce que fait un navigateur est considéré comme une tâche. Cela inclut le rendu, l’analyse HTML, l’exécution de JavaScript, et tout ce sur quoi vous avez ou n’avez pas de contrôle.
Le thread principal « Main Thread » est l’endroit où le navigateur effectue la plupart du travail nécessaire pour afficher une page. Et bien qu’il puisse y avoir des dizaines de tâches à exécuter, le thread principal ne peut traiter qu’une tâche à la fois.
Si une tâche prend plus de 50 millisecondes à être exécutée, elle est classifiée comme une « long task ».
Considérant que le « main thread » ne peut gérer qu’une tâche à la fois, plus la tâche est longue, plus le navigateur sera bloqué pour la traiter.
En d’autres termes, si l’utilisateur tente d’interagir avec la page pendant qu’une « long task » s’exécute, le navigateur devra attendre avant de recevoir une réponse de la requête. Le résultat est une latence d’interaction et donc, un score « INP » moins bon.

Détecter les interactions lentes via les données de terrain

Idéalement, votre parcours dans l’optimisation d’INP commencera avec « les données de terrain ». Celles déterminées en surveillant le parcours de vos utilisateurs sur 28 jours et qu’on peut retrouver dans les rapports de la Google Search Console et lorsqu’on lance un scan avec PageSpeed Insights. Il s’agit de la source de données officielle des Core Web Vitals de Google. Ce CrUX (ou « Chrome User Experience Report ») fournit un résumé des metrics de millions de sites Web, incluant notamment l’avertissement lié à un INP trop long.

Pour rappel, une interaction peut avoir lieu pendant ou après le chargement de la page, lors d’un clic, une frappe de touche du clavier, etc. — Rappel : un “survol” d’élément n’est pas comptabilisé par INP.

Si vous n’avez pas encore de données de terrain, votre première arrêt sera PageSpeed Insights, qui vous aidera à combler ce manque de données en commençant par éliminer les avertissements relatifs au TBT (Total Blocking Time).

Si vous êtes déterminé à réduire l’INP de votre application au maximum et si vous pensez être un développeur web chevronné, l’outil à considérer est la Bibliothèque JavaScript Web-Vitals.

Toutes les données concernant l’INP seront exposées par cette bibliothèque JavaScript « web-vitals ». Vous pouvez consulter le guide étape par étape de Google sur comment exploiter la bibliothèque « web-vital », et comment transmettre les données INP directement à votre Google Analytics.

Les plus rigoureux et expérimentés pourront quant à eux analyser de metrics utilisateur réelles en s’orientant vers des outils de « Real User Monitoring (RUM) », comme on peut en trouver ici et là, notamment sur Github #webvitals.
Il existe aussi des services de RUM payants, comme celui de DebugBear, mais celui-ci est très onéreux et cet important budget serait probablement mieux investit dans d’autres aspects de votre business en ligne. Vous pouvez néanmoins profiter de leur offre de 14 jours d’essai gratuit.

Diagnostiquer les interactions lentes en laboratoire (5 outils)

Idéalement, vous voudrez faire vos premiers tests via PageSpeed Insights et l’outil Lighthouse proposé dans Google Chrome pour les développeurs, et ce, jusqu’à ce que vous ayez assez de données de terrain pour vous confirmer que vous n’avez plus d’interactions trop lentes (et donc, plus aucun problème d’INP).

La metric sur laquelle vous devriez porter une attention particulière est le « Total Blocking Time » (TBT).

Le TBT est une metric qui évalue la réactivité de la page pendant le chargement. Elle est très bien corrélée au INP. Un mauvais score de TBT est un signal indiquant qu’il pourrait y avoir des interactions qui seraient lentes pendant le chargement de la page, et donc, un mauvais INP.

En l’absence de données de terrain, il existe certaines stratégies permettant d’identifier les interactions lentes en laboratoire (c’est-à-dire, via des tests manuels). Ces stratégies incluent la surveillance d’utilisateurs en cours d’interaction sur vos pages / les auto-tests manuels d’interactions au fil de vos pages, ainsi que les interactions avec les pages qui sont en cours de chargement (au moment où le « main thread » est le plus occupé).

Il s’agit d’un travail de fourmi et d’inspection manuel pendant lequel votre mission sera de faire remonter les interactions lentes pouvant impacter l’expérience utilisateur.

En complément, il existe quelques outils qui peuvent aider.

En plus d’utiliser PageSpeed Insights pour vos premiers tests, vous pouvez utiliser Lighthouse avec la fonction Timespan activée pour effectuer des tests de performance.

Lighthouse timespan

En complément, jetez aussi un oeil aux extensions Google Chrome “Site Speed by DebugBear” et “Web Vitals”.

chrome web vitals extension addon

Il existe aussi « INP Debugger », un outil gratuit et très sympa (développé par DebugBear) qui peut vous donner quelques bonnes pistes d’amélioration, comme vous pouvez le voir sur l’illustration ci-dessous.

inp debugger debugbear

Optimiser les interactions

Une fois que vous avez identifié une interaction lente et que vous pouvez la reproduire manuellement en laboratoire (avec vos tests manuels), l’étape suivante est de l’optimiser.

Les interactions peuvent être décomposées en trois phases :

  1. Le délai d’entrée (input delay), qui commence lorsque l’utilisateur initie une interaction avec la page et se termine lorsque les « callbacks » d’événement pour l’interaction commencent à s’exécuter.
  2. Le temps de traitement (processing time), qui représente le temps nécessaire pour que les « callbacks » d’événement s’exécutent jusqu’à leur achèvement.
  3. Le délai de présentation (presentation delay), qui est le temps nécessaire pour que le navigateur présente la prochaine « frame » contenant le résultat visuel de l’interaction.

La somme de ces 3 phases est la latence totale de l’interaction. Il est donc important de savoir comment vous pouvez optimiser chaque partie de l’interaction pour qu’elle s’exécute en aussi peu de temps que possible, tout en vous concentrant sur la page qui prend le plus de temps.

Pour info, avec les <iframes> : lors de l’optimisation des interactions, il est important de comprendre que chaque contexte de navigation aura son propre « main thread ». Cela signifie que la page de niveau supérieur aura un « main thread », mais chaque élément <iframe> sur la page aura également son propre « main thread ».
L’INP sera rapporté au niveau de la page, incluant toute interaction lente sur la page ou tout iframe dans cette page.
Assurez-vous de comprendre dans quelle fenêtre/frame une interaction se produit pour savoir quel « main thread » examiner.
Même avec plusieurs « main threads », les dispositifs à ressources limitées peuvent entraîner un impact ressenti à travers tous ces « threads », même s’ils sont indépendants.

Utiliser des “Web Workers”

Les « web workers » sont un service qui permet à JavaScript de fonctionner indépendamment du thread principal. Ils sont utiles pour exécuter des opérations complexes en arrière-plan.

Par exemple, si vous avez un site « WordPress » rempli d’images, de vidéos et de données, les « web workers » peuvent transférer ces lourds calculs JavaScript vers un thread d’arrière-plan pour éviter de bloquer votre “main thread” et donc, éviter de geler votre interface utilisateur.

Pour utiliser les « web workers », vous pouvez créer 2 fichiers JavaScript (main.js et worker.js).

Par exemple, « main.js » pourra initier les tâches du script « web worker » :

// main.js
if (window.Worker) {
  // Création d'une nouvelle instance Worker
  const myWorker = new Worker('worker-script.js');
  // Envoi d'un message au Worker
  myWorker.postMessage('Hello Worker!');
  // Lecture de messages issus du Worker
  myWorker.onmessage = function(e) {
    console.log('Message reçu du worker', e.data);
  };
} else {
  console.log('Votre navigateur ne support pas les Web Workers.');
}

Ensuite, l’autre fichier “worker.js” pourra contenir les tâches du Web Worker.

Voici un exemple simplifié:

// worker.js
onmessage = function(e) {
  console.log('Message reçu du script principal (main).', e.data);
  // Ici, traitez vos tâches consommatrices de ressources (traitement de données, etc)
  // Enfin, envoi d'un message en retour au script principal (main)
  postMessage('Hello main script !');
}

Pour inclure ces scripts dans votre site web, consultez la documentation de votre technologie ou plateforme spécifique et suivez leur procédure.

Par exemple, les utilisateurs WordPress utiliserons la fonction « wp_enqueue_script » pour inclure les scripts de « web worker » via le fichier « functions.php » de leur thème.

Identifier et réduire le « input delay »

Lorsqu’un utilisateur interagit avec une page, la première partie de cette interaction est le « input delay ». En fonction des autres activités sur la page, les « input delays » peuvent être très longs. Cela pourrait être dû à une activité se produisant sur le « main thread » (peut-être en raison de scripts qui se chargent), la gestion de « fetch », les fonctions de « timer », ou même à partir d’autres interactions qui se produisent en succession rapide et se chevauchent les unes avec les autres.

Quelle que soit la source du « input delay » des interactions, vous voudrez le réduire au maximum afin que les interactions puissent commencer à exécuter des « event callbacks » le plus tôt possible.

Comprendre la relation entre l’évaluation de script et les « long tasks » lors du démarrage

Un aspect critique de l’interactivité dans le cycle de vie d’une page est pendant le démarrage.

Lorsqu’une page se charge, elle va initialement s’afficher, mais il est important de se rappeler que juste parce qu’une page semble complètement affichée, cela ne signifie pas que la page a terminé son chargement. Elle peut être en train de s’occuper du téléchargement de tous les scripts JS différés et de la liste de callbacks planifiés au moment du “onload”.

En fonction du nombre de ressources qu’une page nécessite pour devenir pleinement fonctionnelle, il est possible que les utilisateurs tentent d’interagir avec la page alors qu’elle est encore en cours de chargement.

Une chose qui peut prolonger le « input delay » d’une interaction pendant le chargement d’une page est l’évaluation d’un script. Après qu’un fichier JavaScript ait été récupéré depuis le réseau, le navigateur a encore du travail à faire avant que ce JavaScript puisse s’exécuter ; ce travail comprend l’analyse d’un script (pour s’assurer que sa syntaxe est valide), puis finalement son exécution.

En fonction de la taille d’un script, ce travail peut introduire des « long tasks » sur le « main thread », ce qui retardera le navigateur pour ses futurs réponses à d’autres interactions de l’utilisateur.

Pour garder votre page réactive aux entrées utilisateur pendant le chargement de la page, vous devez déceler les optimisations à mettre en place pour réduire la probabilité de « long tasks » au moment du chargement de la page, et ce, afin que la page reste réactive pendant ce moment crucial du parcours de vos utilisateurs.

Optimiser les “event callbacks”

L’input delay n’est que la première partie de ce que l’INP mesure. Vous devez également vous assurer que les « event callbacks » qui se déclenchent en réponse à une interaction utilisateur peuvent se terminer le plus rapidement possible.

Céder souvent la main au « main thread »

Le meilleur conseil général pour optimiser les « event callbacks » est de faire le moins de travail possible dans ceux-ci. Cependant, si votre logique d’interaction est complexe, vous ne pourrez peut-être réduire que marginalement le travail qu’ils font.

Si vous constatez que c’est le cas pour votre site web, la chose suivante que vous pouvez essayer est de fractionner le travail de vos « event callbacks » en tâches séparées. Cela empêche le travail collectif de devenir une longue tâche qui bloque le « main thread », ce qui permet à d’autres interactions qui seraient autrement en attente sur le « main thread » de se dérouler plus tôt.

Vous l’aurez compris, les tâches longues bloquent le « thread » principal (main thread), empêchant le navigateur d’exécuter les événements d’interaction.

Pour améliorer la réactivité de votre site, il est important de minimiser la charge de travail sur le « thread » principal et d’envisager de diviser les tâches longues.

En divisant les tâches longues en morceaux plus petits, le “main thread” obtient l’opportunité de traiter d’autres tâches et de répondre plus rapidement aux interactions des utilisateurs.

De plus, diviser les tâches longues aide à éviter l’effet de « jank », où les animations et les transitions sur la page deviennent saccadées ou hachées en raison d’un “main thread” submergé.

En garantissant que chaque tâche se termine dans un délai plus court, la page peut maintenir une expérience visuelle plus fluide pour l’utilisateur.

setTimeout est un moyen de fractionner les tâches et d’éviter qu’elle ne se chevauche, car le « callback » passé à celui-ci s’exécute ensuite dans une nouvelle tâche. Vous pouvez l’utiliser pour plus d’ergonomie en cherchant à exécuter la logique de rendu plus tôt après un « event callback ».

setTimeout et setInterval sont des fonctions de minuterie JavaScript couramment utilisées qui peuvent contribuer au “input delay”.
setTimeout planifie un « callback » qui doit s’exécuter après un temps spécifié, et bien qu’il puisse aider à éviter de longues tâches, cela dépend de quand le « timeout » se produit et s’il coïncide avec des interactions utilisateur.
setInterval de son côté planifie un « callback » pour s’exécuter répétitivement à un intervalle spécifié. De ce fait, il est plus susceptible d’interférer avec les interactions utilisateur. Sa nature récurrente augmente le retard d’entrée et peut affecter la réactivité des interactions. Si vous avez le contrôle sur les « timers » de votre code, évaluez leur nécessité et réduisez leur charge de travail autant que possible.

Envisagez de supprimer les callbacks inutiles (ou les retarder)

Assurez-vous que vos “event callbacks” coûteux en ressources sont vraiment nécessaire. Sinon, envisagez de supprimer complètement le code, ou si cela n’est pas possible, retardez son exécution jusqu’à un moment plus approprié où le main thread est moins occupé.

Différez le travail non lié au rendu

Les tâches longues peuvent être interrompues en cédant la place au « main thread ».

Lorsque vous cédez la place au « main thread », vous mettez essentiellement en pause la tâche actuelle et divisez le travail restant en tâches séparées. Cela permet au « renderer » de gérer les mises à jour de l’interface utilisateur qui ont été traitées plus tôt dans le rappel d’événement. En cédant, vous permettez au « renderer » d’exécuter les modifications en attente et assurez une mise à jour de l’interface utilisateur fluide et en temps voulu.

Évitez les travaux excessifs ou inutiles dans les callbacks de « requestAnimationFrame »

La méthode « requestAnimationFrame » indique au navigateur que vous souhaitez effectuer une animation et demande que le navigateur appelle une fonction spécifiée pour mettre à jour une animation juste avant la prochaine impression.

Le callback « requestAnimationFrame() » fait partie de la phase de rendu de la boucle d’événement et doit se terminer avant que la frame suivante puisse être affichée. Si vous utilisez « requestAnimationFrame() » pour des tâches non liées aux changements de l’interface utilisateur, il est essentiel d’envisager de retarder le rendu de la frame suivante.

Évitez donc de les utiliser inutilement.

Différez les callbacks « ResizeObserver »

L’interface « ResizeObserver » signale les changements de dimensions des éléments de contenu, de bordure de blocs, ou des blocs englobants des « SVGElement ».

Les callbacks « ResizeObserver » sont exécutés avant le rendu et peuvent potentiellement retarder la présentation des frames suivantes s’ils impliquent des tâches intensives en ressources. Semblable aux “event callbacks”, il est conseillé de différer toute logique inutile non requise pour les frames qui doivent venir ensuite.

Fournir un feedback immédiat

Certaines interactions peuvent entraîner des retards de réponse notables, comme la soumission d’un formulaire avec beaucoup de données ou des fichiers joints.

C’est dans ce genre de cas de figure qu’il est indispensable de fournir un feedback immédiat.

Cette pratique donne directement aux utilisateurs une indication visuelle que le site Web a reçu et traite leur demande.

Grâce à ce feedback immédiat, les utilisateurs ne se demandent pas si leur demande a bien été prise en compte par le site Web. Ils le savent puisqu’ils en ont eu la confirmation.

Bien sûr, cela ne réduira pas le temps de traitement total réel, mais cela donnera l’impression d’une performance plus rapide et aidera l’utilisateur à patienter jusqu’à la réponse du serveur et/ou du navigateur web.

Pour vous donner encore plus d’idées sur les feedbacks immédiats qui peuvent être mis en place, voici quelques exemples :

  • Validation des champs de formulaire : par exemple, si un utilisateur a mal saisi son adresse email et qu’elle est mal formatée, il faudrait afficher immédiatement un message d’erreur plutôt que d’attendre qu’il soumette le formulaire pour l’en avertir.
  • Info bulle de confirmation : pour des actions telles que l’ajout d’un article dans un panier, il est bon d’afficher un message confirmant que l’action a été prise en compte et réussie.
  • Barre de chargement : affichez un « spinner » ou une « barre de progession » lorsqu’un processus est en cours de traitement en arrière plan, surtout lorsque l’utilisateur attend l’affichage de nouvelles données.
Navigateur avec Loader / Spinner / Animation au chargement de la page

Effectuer le rendu pour permettre au travail de se produire plus tôt

Une technique de cession plus avancée consiste à structurer le code dans vos callbacks d’événement pour limiter ce qui est exécuté localement et afficher les mises à jour visuelles directement à la prochaine “frame”. Tout le reste peut être différé à une tâche ultérieure. Déjà, cela maintient les callbacks légers et agiles, mais améliore également le temps de rendu pour les interactions, puisqu’on ne bloque pas les mises à jour visuelles sur le code de callback d’événement.

Par exemple, imaginez un éditeur de texte riche qui formate le texte au fur et à mesure que vous tapez, mais met également à jour d’autres aspects de l’UI en réponse à ce que vous écrivez (comme le compteur de mots ou la mise en évidence des fautes d’orthographe par exemple). De plus, l’application peut également avoir besoin de sauvegarder ce que vous avez écrit au fur et à mesure, comme avec les révisions de WordPress.

Dans cet exemple, les 4 choses suivantes doivent se produire en réponse aux caractères tapés par l’utilisateur. Cependant, seul le premier élément doit être fait avant la présentation de la prochaine “frame”.

  1. Mettre à jour la boîte de texte avec ce que l’utilisateur a tapé et appliquer toute la mise en forme requise.
  2. Mettre à jour la partie de l’UI qui affiche le compteur de mots actuel.
  3. Exécuter la logique pour vérifier les fautes d’orthographe.
  4. Sauvegarder les modifications les plus récentes (localement et/ou dans la base de données).

Le code pour faire cela pourrait ressembler à ce qui suit :

textBox.addEventListener('input', (inputEvent) => {
  // Mettre à jour l'interface utilisateur immédiatement pour que les modifications apportées soient visibles dès la prochaine frame
  updateTextBox(inputEvent);

  // Utilisez `setTimeout` pour différer tout autre travail jusqu'au moins la prochaine "frame" en mettant en file d'attente une tâche dans un callback `requestAnimationFrame()`
  requestAnimationFrame(() => {
    setTimeout(() => {
      const text = textBox.textContent;
      updateWordCount(text);
      checkSpelling(text);
      saveChanges(text);
    }, 0);
  });
});

La visualisation suivante montre comment différer toute mise à jour non critique jusqu’après la prochaine “frame” peut réduire le temps de traitement et donc la latence globale d’interaction.

interaction latency before after optimisation inp

Bien que l’utilisation de setTimeout() à l’intérieur d’un appel requestAnimationFrame() dans l’exemple de code précédent soit un peu complexe, c’est une méthode efficace qui fonctionne dans tous les navigateurs pour garantir que le code non critique ne bloque pas la prochaine “frame”.

Éviter le thrashing de layout

Le thrashing de layout — parfois appelé layout forcé synchrone — est un problème de performance de rendu où le layout se produit de manière synchrone. Il se produit lorsque vous mettez à jour les styles en « JavaScript », puis les lisez dans la même tâche — et il y a de nombreuses propriétés en « JavaScript » qui peuvent provoquer le thrashing de layout.

Avoid layout thrashing inp optimisation

Un exemple de thrashing de layout, tel qu’affiché dans le panneau de performance des outils de développement Chrome. Les tâches de rendu qui impliquent du thrashing de layout seront notées avec un triangle rouge dans le coin supérieur droit de la partie du “call stack”, souvent étiquetées Recalculate Style ou Layout.

Le thrashing de layout est un bottleneck de performance, car en mettant à jour les styles puis en demandant immédiatement les valeurs de ces styles en « JavaScript », le navigateur est forcé d’effectuer un travail de layout synchrone qu’il aurait pu effectuer de manière asynchrone plus tard après que les callbacks d’événements aient fini de s’exécuter.

Minimiser le délai de présentation

Le « délai de présentation » (presentation delay) d’une interaction marque l’intervalle depuis la fin de l’exécution des callbacks d’événements d’une interaction, jusqu’au moment où le navigateur est capable d’afficher la prochaine “frame” montrant les changements visuels résultants.

Minimiser la taille du DOM

Quand le « DOM » d’une page est petit, le travail de rendu se termine généralement rapidement. Cependant, lorsque les « DOMs » deviennent très grands, le travail de rendu a tendance à augmenter avec la taille croissante du « DOM », ce qui a un impact sur la capacité du navigateur à afficher une page rapidement et efficacement.

Plus le DOM est grand, plus il est “resource-intensive” pour l’affichage initiale de la page et pour effectuer les mises à jour ultérieures, suite aux interactions et pendant le cycle de vie de la page.

La relation entre le travail de rendu et la taille du « DOM » n’est pas linéaire, mais de grands « DOMs » nécessitent plus de travail de rendu que des petits « DOMs ».

Un grand « DOM » est problématique dans 2 cas :

  1. Lors du rendu initial de la page, où un grand « DOM » 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” en ressources, et donc augmenter le temps nécessaire pour que le navigateur présente la prochaine frame.

Gardez à l’esprit qu’il existe des cas où la taille des « DOMs » ne peut pas être significativement réduite.

Bien qu’il existe des approches que vous pouvez adopter pour réduire la taille initiale du « DOM » plus petite, comme la réduction des balises HTML imbriquées ou l’ajout des éléments au « DOM » suite à des interactions utilisateurs, ces techniques peuvent seulement aller jusqu’à un certain point.

Utilisez « content-visibility » pour faire du lazyloading (chargement différé des éléments hors écran)

Déjà pour optimiser le FID et encore plus pour l’INP, il est nécessaire de minimiser et d’optimiser les temps d’exécution JavaScript en vérifiant davantage les délais d’interactions qu’on retrouve tout au long de la vie de la page. Mais il est encore plus crucial également de mettre en place le chargement différé des contenus “hors écran” en reportant les scripts non essentiels de manière aussi agressive que possible.

Une manière dont vous pouvez limiter la quantité de travail de rendu durant le chargement de la page, et le travail de rendu en réponse aux interactions des utilisateurs consiste à s’appuyer sur la propriété CSS « content-visibility », qui revient effectivement à rendre “lazyload” les éléments à mesure qu’ils approchent du “viewport” (zone visible sur l’écran).

Bien que « content-visibility » puisse nécessiter un peu de pratique pour être utilisée efficacement par les développeurs, cela vaut la peine de s’y intéresser afin d’obtenir une réduction du temps de rendu qui peut améliorer l’INP de vos pages !

Soyez conscient des coûts de performance des rendus HTML utilisant JavaScript

Là où il y a du HTML, il y a du parsing de HTML, et lorsque le navigateur a fini de parser le HTML en un DOM, il doit appliquer des styles, effectuer des calculs de mise en page, et ensuite afficher cette mise en page résultante. C’est un coût de ressources inévitable pour le navigateur, mais la manière dont vous procédez au rendu du HTML en optimisant votre code est importante.

Lorsque le serveur envoie du HTML, il arrive dans le navigateur sous forme de flux qui arrive par morceaux. Le navigateur optimise en parsant des morceaux de flux au fur et à mesure qu’ils arrivent, en les affichant petit à petit. C’est une optimisation de performance dans le sens où le navigateur reprend périodiquement le chargement de la page, ce qui ne mange pas de pain.

La première visite sur un site Web impliquera toujours une certaine quantité de HTML, mais une approche courante commence avec un petit morceau initial de HTML. Ensuite, JavaScript est utilisé pour charger d’avantage de contenu.

D’autres contenus complémentaires peuvent aussi être affichés à la suite d’interactions utilisateur. Cela est généralement appelé le modèle d’application monopage (SPA ou « single-page application »). Un inconvénient de ce schéma est que, en affichant du HTML avec JavaScript, vous avez non seulement un coût de traitement JavaScript et HTML, mais aussi un navigateur qui va bloquer le processus avant d’avoir fini d’analyser le HTML et de l’afficher.

Cependant, il est vital de se rappeler que même les sites Web qui ne sont pas des « SPAs » impliqueront probablement une certaine quantité de rendu HTML à travers JavaScript, imprimée à la suite d’interactions, cela est généralement acceptable, tant que vous n’imprimez pas de grandes quantités de HTML dans le navigateur, ce qui peut retarder la présentation de la prochaine frame. Cependant, il est important de comprendre l’impact sur la performance de cette approche du rendu HTML dans le navigateur, et comment cela peut impacter la réactivité de votre site Web suite aux interactions utilisateur si vous chargez beaucoup de HTML via le JavaScript.

Conclusion sur l’amélioration du score d’INP

Améliorer l’INP de votre site est un processus itératif. Parfois, corriger une source de lenteur INP ne suffit pas et sa correction peut cacher une autre source de lenteur, surtout si votre site Web contient beaucoup d’éléments interactifs.

La clé pour améliorer l’INP est la persévérance, mais avec le temps, vous pouvez amener la réactivité de votre page à un niveau où les utilisateurs seront satisfaits de l’expérience que vous leur offrez, et où vous maîtriserez tous les rouages de l’INP pour vos autres développements.

Si vous pensez avoir tout fait pour obtenir un score d’INP satisfaisant ou si ces explications techniques vous semble trop complexes en regard de vos compétences, n’hésitez pas à vous renseigner sur les Solutions d’Hébergement Web EasyHoster (optimisées pour WordPress et incluant un support technique avancé), ainsi que nos Packs d’interventions de minimum 10 heures, pouvant être utilisés pour obtenir des optimisations Core Web Vitals de la part de notre équipe.

Le site WordPress speed.easyhoster.net ➚ permet de tester le potentiel des solutions d'Hébergement Web EasyHoster.