Optimiser le délai d'entrée

Découvrez ce qu'est le délai d'entrée et apprenez des techniques pour le réduire et améliorer l'interactivité.

Jeremy Wagner
Jeremy Wagner

Les interactions sur le Web sont des choses compliquées, car toutes sortes d'activités se produisent dans le navigateur pour les conduire. Toutefois, ils ont tous en commun un certain délai d'entrée avant l'exécution de leurs rappels d'événements. Dans ce guide, vous allez découvrir ce qu'est le délai d'entrée et comment le réduire afin que les interactions avec votre site Web soient plus rapides.

Qu'est-ce que le délai d'entrée ?

Le délai d'entrée correspond à la période entre le moment où l'utilisateur interagit pour la première fois avec une page (par exemple, lorsqu'il appuie sur un écran, d'un clic de souris ou d'une touche) jusqu'au moment où les rappels d'événement liés à l'interaction commencent à s'exécuter. Chaque interaction commence par un délai d'entrée spécifique.

Visualisation simplifiée du délai d'entrée. À gauche, un dessin au trait représente le curseur d'une souris avec une étoile derrière lui, ce qui indique le début d'une interaction. À droite, une illustration représentant un engrenage indique le moment où les gestionnaires d'événements d'une interaction commencent à s'exécuter. L'espace entre les deux est indiqué comme délai d'entrée avec une accolade.
Mécanisme derrière le délai d'entrée. Lorsqu'une entrée est reçue par le système d'exploitation, elle doit être transmise au navigateur avant le début de l'interaction. Cette opération prend un certain temps et peut être augmentée par le thread principal existant.

Une partie du délai d'entrée est inévitable: le système d'exploitation a toujours besoin d'un certain temps pour reconnaître un événement d'entrée et le transmettre au navigateur. Cependant, cette partie du délai d'entrée n'est souvent même pas perceptible, et d'autres éléments qui se produisent sur la page peuvent retarder les entrées de manière suffisamment longues pour causer des problèmes.

Comprendre le délai d'entrée

De manière générale, chaque étape d'une interaction doit être la plus courte possible afin que votre site Web ait le plus de chances d'atteindre le seuil de performances satisfaisante pour la métrique "Interaction to Next Paint" (INP), quel que soit l'appareil de l'utilisateur. Garder le retard d'entrée sous contrôle n'est qu'une partie de l'atteinte de ce seuil.

Vous pourriez être tenté de consulter les seuils FID (First Input Delay) pour déterminer si des retards d'entrée sont pris en compte, mais le "bon" seuil pour le FID est de 100 millisecondes ou moins. Si vous dépassez ce seuil, vous alloueriez la moitié de votre budget à l'INP uniquement pour le délai d'entrée. Cette approche est déconseillée si vous considérez qu'une interaction nécessite également du temps pour exécuter des rappels d'événements et pour que le navigateur peigne le frame suivant.

Pour atteindre le "bon" seuil de l'INP, vous devez viser le délai d'entrée le plus court possible, mais ne vous attendez pas à l'éliminer complètement, car c'est impossible. Tant que vous évitez de travailler trop au niveau du thread principal lorsque les utilisateurs tentent d'interagir avec votre page, votre délai d'entrée doit être suffisamment faible pour éviter les problèmes.

Réduire le délai d'entrée

Comme indiqué précédemment, il est inévitable d'avoir un certain décalage d'entrée. En revanche, il est possible d'éviter certains retards d'entrée. Voici quelques points à prendre en compte si vous rencontrez des problèmes de délais d'entrée importants.

Éviter les minuteurs récurrents qui déclenchent trop de travail dans le thread principal

En JavaScript, deux fonctions de minuteur couramment utilisées peuvent contribuer au délai d'entrée: setTimeout et setInterval. La différence entre les deux est que setTimeout planifie l'exécution d'un rappel après un délai spécifié. setInterval, en revanche, planifie un rappel pour qu'il s'exécute toutes les n millisecondes indéfiniment ou jusqu'à l'arrêt du minuteur avec clearInterval.

setTimeout ne pose pas de problème en soi. En réalité, il peut être utile pour éviter les longues tâches. Toutefois, cela dépend du moment de l'expiration du délai, et de la tentative d'interaction de l'utilisateur avec la page lors de l'exécution du rappel d'expiration.

De plus, setTimeout peut être exécuté dans une boucle ou de manière récursive, où il agit davantage comme setInterval, mais de préférence ne pas planifier l'itération suivante avant que la précédente ne soit terminée. Bien que cela signifie que la boucle cède au thread principal chaque fois que setTimeout est appelé, vous devez veiller à ce que son rappel n'entraîne pas un travail excessif.

setInterval exécute un rappel à intervalles réguliers et risque donc d'entraver les interactions. En effet, contrairement à une seule instance d'un appel setTimeout, qui est un rappel ponctuel qui peut gêner une interaction de l'utilisateur, la nature récurrente de setInterval augmente beaucoup plus la probabilité qu'il empêche une interaction, ce qui augmente le délai d'entrée de l'interaction.

Capture d'écran du Profileur de performances dans les outils pour les développeurs Chrome, qui montre le délai de saisie. Une tâche déclenchée par une fonction de minuteur se produit juste avant qu'un utilisateur ne commence une interaction de clic. Cependant, le minuteur prolonge le délai d'entrée, ce qui retarde l'exécution des rappels d'événements de l'interaction.
Minuteur enregistré par un appel setInterval précédent contribuant au délai d'entrée, comme illustré dans le panneau "Performances" des outils pour les développeurs Chrome. Le délai d'entrée ajouté entraîne l'exécution des rappels d'événement pour l'interaction plus tard qu'ils ne le pourraient autrement.

Si des minuteurs s'exécutent dans le code propriétaire, c'est vous qui les contrôlez. Évaluez si vous en avez besoin ou faites de votre mieux pour réduire le travail qu’ils contiennent autant que possible. En revanche, les minuteurs des scripts tiers fonctionnent différemment. Souvent, vous n'avez pas le contrôle sur ce que fait un script tiers et la résolution des problèmes de performance dans le code tiers implique souvent de travailler avec les partenaires pour déterminer si un script tiers est nécessaire et, le cas échéant, établir un contact avec un fournisseur de scripts tiers pour déterminer ce qui peut faire pour résoudre les problèmes de performance qu'ils peuvent causer sur votre site Web.

Éviter les longues tâches

Une façon d'atténuer les longs délais d'entrée est d'éviter les longues tâches. Lorsque le thread principal est trop sollicité lors des interactions, cela augmente le délai d'entrée de ces threads avant que les longues tâches n'aient eu le temps de se terminer.

Visualisation de la durée pendant laquelle les tâches prolongent le délai d'entrée. En haut, une interaction se produit peu de temps après l'exécution d'une seule tâche longue, ce qui entraîne un délai d'entrée important qui entraîne l'exécution des rappels d'événements beaucoup plus tard qu'ils ne le devraient. En bas, une interaction se produit à peu près au même moment, mais la tâche longue est divisée en plusieurs tâches plus petites en cédant, ce qui permet aux rappels d'événements de l'interaction de s'exécuter beaucoup plus tôt.
Ce schéma montre ce qu'il advient des interactions lorsque les tâches sont trop longues et que le navigateur ne peut pas répondre assez rapidement aux interactions, par rapport aux tâches plus longues divisées en tâches plus petites.

En plus de réduire la quantité de travail que vous effectuez dans une tâche (et vous devez toujours faire le moins de travail possible sur le thread principal), vous pouvez améliorer la réactivité aux entrées utilisateur en divisant les longues tâches.

Faites attention au chevauchement des interactions

L'optimisation de l'INP peut être particulièrement difficile en cas d'interactions qui se chevauchent. Une fois que vous avez interagi avec un élément, vous effectuez une autre interaction avec la page avant que l'interaction initiale ait eu le temps d'afficher l'image suivante.

Représentation du moment où les tâches peuvent se chevaucher pour entraîner de longs délais de saisie. Dans cette représentation, un clic se superpose à une interaction de type "keydown" afin d'augmenter le délai de saisie de cette interaction.
Visualisation de deux interactions simultanées dans le Profileur de performances des outils pour les développeurs Chrome. Les opérations de rendu lors de l'interaction initiale de clic entraînent un délai de saisie pour l'interaction suivante avec le clavier.

Les sources de chevauchement d'interactions peuvent être aussi simples que les interactions des utilisateurs sur une courte période. Cela peut se produire lorsque les utilisateurs saisissent du texte dans des champs de formulaire, alors que de nombreuses interactions avec le clavier peuvent se produire en très peu de temps. Si le travail sur un événement clé est particulièrement coûteux (par exemple, dans le cas courant des champs de saisie semi-automatique où des requêtes réseau sont envoyées à un backend), vous disposez de plusieurs options:

  • Envisagez de rejeter les entrées pour limiter le nombre de fois où un rappel d'événement s'exécute sur une période donnée.
  • Utilisez AbortController pour annuler les requêtes fetch sortantes afin que le thread principal ne soit pas encombré lors du traitement des rappels fetch. Remarque: La propriété signal d'une instance AbortController peut également être utilisée pour annuler des événements.

Les animations coûteuses peuvent également entraîner une augmentation du délai d'entrée dû au chevauchement des interactions. En particulier, les animations en JavaScript peuvent déclencher de nombreux appels requestAnimationFrame, ce qui peut gêner les interactions de l'utilisateur. Pour contourner ce problème, utilisez autant que possible des animations CSS afin d'éviter de mettre en file d'attente des images d'animation potentiellement coûteuses. Toutefois, si vous procédez ainsi, veillez à éviter les animations non composées, de sorte qu'elles s'exécutent principalement sur le thread GPU et le thread compositeur, et non sur le thread principal.

Conclusion

Même si les délais d'entrée ne représentent pas la majorité du temps nécessaire à l'exécution de vos interactions, il est important de comprendre que chaque partie d'une interaction prend un certain temps que vous pouvez réduire. Si vous observez un long délai de saisie, vous avez la possibilité de le réduire. En évitant les rappels récurrents de minuteur, la séparation des tâches longues et le fait d'être conscient du chevauchement potentiel des interactions, vous pouvez réduire le délai de saisie, et ainsi accélérer l'interactivité pour les utilisateurs de votre site Web.

Image principale de Unsplash, par Erik Mclean.