Vitesse de défilement par défaut de la molette

Sahel Sharify
Sahel Sharify

Pour améliorer les performances de défilement/zoom wheel, nous encourageons les développeurs à enregistrer les écouteurs d'événements wheel et mousewheel comme passifs en transmettant l'option {passive: true} à addEventListener(). Enregistrer les écouteurs d'événements comme passifs indique au navigateur qu'ils n'appelleront pas preventDefault() et que le navigateur peut effectuer des défilements et des zooms en toute sécurité sans bloquer les écouteurs.

Le problème est que le plus souvent, les écouteurs d'événements de la roue sont conceptuellement passifs (n'appellent pas preventDefault()), mais ne sont pas explicitement spécifiés comme tels, ce qui oblige le navigateur à attendre la fin du traitement des événements JS avant de commencer à faire défiler ou à zoomer, même si l'attente n'est pas nécessaire. Dans Chrome 56, nous avons corrigé ce problème pour touchstart et touchmove, et cette modification a ensuite été adoptée à la fois par Safari et Firefox. Comme vous pouvez le voir dans la vidéo de démonstration que nous avons réalisée à l'époque, ce comportement s'est produit, car il générait un retard notable dans la réponse du défilement. Dans Chrome 73, nous avons appliqué la même intervention aux événements wheel et mousewheel.

L'intervention

Notre objectif avec ce changement est de réduire le temps nécessaire pour mettre à jour l'affichage une fois que l'utilisateur commence à faire défiler l'écran à l'aide de la molette ou du pavé tactile sans que les développeurs n'aient à modifier le code. Nos métriques montrent que 75% des écouteurs d'événements wheel et mousewheel enregistrés sur les cibles racines (fenêtre, document ou corps) ne spécifient aucune valeur pour l'option passive, et plus de 98% d'entre eux n'appellent pas preventDefault(). Dans Chrome 73, nous modifions les écouteurs wheel et mousewheel enregistrés sur les cibles racines (fenêtre, document ou corps) pour les rendre passifs par défaut. Cela signifie qu'un écouteur d'événements tel que:

window.addEventListener("wheel", func);

devient équivalent à:

window.addEventListener("wheel", func, {passive: true});

De plus, l'appel de preventDefault() dans l'écouteur sera ignoré avec l'avertissement suivant des outils de développement:

[Intervention] Unable to preventDefault inside passive event listener due
to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312

Casse et conseils

Dans la grande majorité des cas, aucune faille n'est observée. Ce n'est que dans de rares cas (moins de 0,3% des pages d'après nos métriques) qu'un défilement ou un zoom involontaire peut se produire, car l'appel preventDefault() est ignoré dans les écouteurs traités par défaut comme passifs. Votre application peut déterminer si elle rencontre ce problème en vérifiant si l'appel de preventDefault() a eu un effet via la propriété defaultPrevented. La correction des cas affectés est relativement simple: transmettez {passive: false} à addEventListener() pour remplacer le comportement par défaut et conserver l'écouteur d'événements comme bloquant.