L'entrée est envoyée au compositeur
Ceci est la dernière des quatre parties de notre série d'articles de blog consacrées à Chrome. en examinant comment il gère notre code pour afficher un site Web. Dans l'article précédent, nous avons étudié le processus de rendu et découvert le compositeur. Dans ce post, nous allons comment le compositeur permet une interaction fluide lorsqu'une entrée utilisateur est saisie.
Saisir les événements du point de vue du navigateur
Lorsque vous entendez "Événements d'entrée" vous pourriez ne penser qu’à une saisie dans une zone de texte ou à un clic de souris, mais du point de vue du navigateur, la saisie désigne tout geste de l'utilisateur. Le défilement de la molette de la souris est une entrée et un événement tactile ou au passage de la souris est également un événement d'entrée.
Lorsque l'utilisateur effectue un geste, comme un toucher sur un écran, le processus du navigateur est celui qui reçoit
le geste d'ouverture. Toutefois, le processus du navigateur ne connaît que l'endroit où ce geste s'est produit,
le contenu d'un onglet est géré par le processus du moteur de rendu. Le processus du navigateur envoie donc l'événement
(comme touchstart
) et ses coordonnées au processus du moteur de rendu. Le processus du moteur de rendu gère
en trouvant la cible de l'événement et en exécutant les écouteurs d'événements associés.
![événement d'entrée](https://developer.chrome.com/static/blog/inside-browser-part4/image/input-event-265a73164e715.png?authuser=6&hl=fr)
Le compositeur reçoit des événements d'entrée
Dans l'article précédent, nous avons vu comment le compositeur pouvait gérer de manière fluide le défilement en composant de couches rastérisées. Si aucun écouteur d'événements d'entrée n'est associé à la page, le fil de discussion du compositeur peut créer un nouveau cadre composite complètement indépendant du thread principal. Mais que se passe-t-il si un événement étaient associés à la page ? Comment le fil de discussion du compositeur déterminera-t-il si l'événement a besoin à traiter ?
Comprendre la région à défilement non rapide
L'exécution de JavaScript étant la tâche du thread principal, lorsqu'une page est composée, le thread du compositeur marque une région de la page à laquelle des gestionnaires d'événements sont associés en tant que "Région à défilement non rapide". Par contenant ces informations, le thread compositeur peut envoyer l'événement d'entrée au thread principal. si l'événement se produit dans cette région. Si l'événement d'entrée provient de l'extérieur de cette région, le thread compositeur continue la composition du nouveau frame sans attendre le thread principal.
![zone à défilement limité et non rapide](https://developer.chrome.com/static/blog/inside-browser-part4/image/limited-non-fast-scrollab-376be5ee2cd6b.png?authuser=6&hl=fr)
Soyez prudent lorsque vous écrivez des gestionnaires d'événements
La délégation d'événements est un modèle courant de gestion des événements en développement Web. Puisque les événements s'affichent, associer un gestionnaire d'événements à l'élément le plus haut et déléguer des tâches en fonction de la cible de l'événement Toi avez peut-être vu ou écrit du code comme ci-dessous.
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault();
}
});
Étant donné que vous n'avez besoin d'écrire qu'un seul gestionnaire d'événements pour tous les éléments, l'ergonomie de cet événement le schéma de délégation sont attrayants. Toutefois, si vous examinez ce code du point de vue du navigateur la page entière est désormais marquée comme une zone à défilement lent. Cela signifie que même si votre l'application ne se soucie pas des entrées provenant de certaines parties de la page, le fil de discussion du compositeur doit communiquer avec le thread principal et l'attendre chaque fois qu'un événement d'entrée se produit. Ainsi, la capacité de défilement fluide du compositeur est éliminée.
![zone pleine page à défilement non rapide](https://developer.chrome.com/static/blog/inside-browser-part4/image/full-page-non-fast-scroll-dd3010cc3ee0f.png?authuser=6&hl=fr)
Pour éviter cela, vous pouvez transmettre passive: true
options dans votre événement
l'écouteur. Cela indique au navigateur que vous souhaitez toujours écouter l'événement dans le thread principal,
mais le compositeur peut aussi créer un frame.
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault()
}
}, {passive: true});
Vérifier si l'événement peut être annulé
![défilement de page](https://developer.chrome.com/static/blog/inside-browser-part4/image/page-scroll-2cf8d804f8587.png?authuser=6&hl=fr)
Imaginons que vous souhaitiez limiter la direction de défilement au défilement horizontal d'une page.
L'utilisation de l'option passive: true
dans votre événement de pointeur signifie que le défilement de la page peut être fluide, mais
le défilement vertical a peut-être commencé au moment où vous souhaitez preventDefault
afin de limiter
sens de défilement. Pour ce faire, utilisez la méthode event.cancelable
.
document.body.addEventListener('pointermove', event => {
if (event.cancelable) {
event.preventDefault(); // block the native scroll
/*
* do what you want the application to do here
*/
}
}, {passive: true});
Vous pouvez également utiliser une règle CSS telle que touch-action
pour éliminer complètement le gestionnaire d'événements.
#area {
touch-action: pan-x;
}
Trouver la cible de l'événement
![test de positionnement](https://developer.chrome.com/static/blog/inside-browser-part4/image/hit-test-39f1d20855064.png?authuser=6&hl=fr)
Lorsque le thread compositeur envoie un événement d'entrée au thread principal, la première chose à exécuter est un hit. pour trouver l'événement cible. Le test de positionnement utilise les données d'enregistrement de peinture qui ont été générées dans le rendu pour savoir ce qui se trouve sous les coordonnées du point où l'événement s'est produit.
Réduire les distributions d'événements au thread principal
Dans le post précédent, nous avons parlé de la façon dont notre affichage standard actualise l'écran 60 fois par seconde et comment suivre la cadence pour une animation fluide. Pour la saisie, un écran tactile classique un appareil envoie des événements tactiles 60 à 120 fois par seconde et une souris classique 100 fois par seconde seconde. L'événement d'entrée est plus fidèle que ce que notre écran peut actualiser.
Si un événement continu tel que touchmove
a été envoyé au thread principal 120 fois par seconde, il
peut déclencher un nombre excessif de tests de positionnement et d'exécution de JavaScript,
l'écran peut s'actualiser.
![événements non filtrés](https://developer.chrome.com/static/blog/inside-browser-part4/image/unfiltered-events-5c569da8f6466.png?authuser=6&hl=fr)
Pour limiter les appels excessifs au thread principal, Chrome fusionne les événements continus (tels que
wheel
, mousewheel
, mousemove
, pointermove
, touchmove
) et retarde l'expédition jusqu'au
juste avant le prochain requestAnimationFrame
.
![événements fusionnés](https://developer.chrome.com/static/blog/inside-browser-part4/image/coalesced-events-42fbb3813612d.png?authuser=6&hl=fr)
Tous les événements distincts tels que keydown
, keyup
, mouseup
, mousedown
, touchstart
et touchend
sont expédiés immédiatement.
Utiliser getCoalescedEvents
pour obtenir des événements dans le cadre
Pour la plupart des applications Web, les événements fusionnés devraient suffire à offrir une bonne expérience utilisateur.
Toutefois, si vous créez des éléments tels que le dessin d'une application et que vous placez un chemin d'accès basé sur
touchmove
, vous risquez de perdre des coordonnées entre les deux pour tracer une ligne lisse. Dans ce cas,
vous pouvez utiliser la méthode getCoalescedEvents
dans l'événement de pointeur pour obtenir des informations sur ces
des événements fusionnés.
![getCoalescedEvents](https://developer.chrome.com/static/blog/inside-browser-part4/image/getcoalescedevents-ab59c1cb92e1b.png?authuser=6&hl=fr)
window.addEventListener('pointermove', event => {
const events = event.getCoalescedEvents();
for (let event of events) {
const x = event.pageX;
const y = event.pageY;
// draw a line using x and y coordinates.
}
});
Étapes suivantes
Dans cette série, nous avons abordé le fonctionnement
interne d'un navigateur Web. Si vous n’avez jamais réfléchi à la raison
Les outils de développement vous recommandent d'ajouter {passive: true}
à votre gestionnaire d'événements ou d'expliquer pourquoi vous pourriez écrire async
dans votre tag de script, j'espère que cette série vous aidera à comprendre pourquoi un navigateur a besoin de ces
des informations pour offrir une expérience Web plus rapide et plus fluide.
Utiliser Lighthouse
Si vous voulez que votre code soit agréable pour le navigateur, mais que vous ne savez pas par où commencer, Lighthouse est un outil qui exécute un audit de n'importe quel site Web et vous donne une rendre compte de ce qui est bien fait et de ce qui doit être amélioré. En parcourant la liste des audits vous donne également une idée de ce qui compte pour un navigateur.
Découvrez comment mesurer les performances
Les ajustements de performances pouvant varier d'un site à l'autre, il est essentiel de mesurer les performances de votre site et décider ce qui convient le mieux à votre site. L'équipe des outils pour les développeurs Chrome propose des tutoriels comment mesurer les performances de votre site.
Ajouter une règle de fonctionnalité à votre site
Si vous souhaitez ajouter une étape supplémentaire, sachez que les Règles relatives aux fonctionnalités sont un nouveau
de plateforme web qui peut être un garde-fous pour vous lorsque vous construisez votre projet. Activation...
le règlement sur les fonctionnalités garantit le comportement précis de votre appli et vous évite de commettre des erreurs.
Par exemple, pour vous assurer que votre application ne bloquera jamais l'analyse, vous pouvez l'exécuter sur
de scripts synchrones. Lorsque sync-script: 'none'
est activé, le code JavaScript bloquant de l'analyseur
leur exécution. Ainsi, votre code ne bloque pas l'analyseur, et l'analyse
le navigateur n'a pas à mettre en pause l'analyseur.
Conclusion
![merci](https://developer.chrome.com/static/blog/inside-browser-part4/image/thank-you-cae9a20f3c237.png?authuser=6&hl=fr)
Quand j'ai commencé à créer des sites Web, je ne me préoccupais presque que de la façon dont j'écrivais mon code et ce que m’aiderait à être plus productif. Ces points sont importants, mais nous devons également réfléchir à la façon dont le code que nous écrivons. Les navigateurs modernes investissent et continuent d'investir dans des moyens afin d'améliorer l'expérience des utilisateurs sur le Web. Être gentil avec le navigateur en organisant notre code, et améliorer l'expérience utilisateur. J'espère que vous me rejoindrez dans la quête d'une bonne expérience avec les navigateurs !
Merci beaucoup à tous ceux qui ont examiné les premières versions de cette série, y compris, mais sans s'y limiter à): Alex Russell, Paul Irish, Meggin Kearney, Eric Bidelman, Mathias Bynens, Addy Osmani, Kinuko Yasuda, Nasko Oskov, et Charlie Reis.
Avez-vous apprécié cette série ? Si vous avez des questions ou des suggestions pour le prochain post, N'hésitez pas à laisser un commentaire dans la section ci-dessous ou à envoyer un e-mail à l'adresse @kosamari. sur Twitter.