Input in arrivo nel compositore
Questa è l'ultima delle quattro parti della serie di blog dedicata all'interno di Chrome. alla ricerca di come gestisce il nostro codice per visualizzare un sito web. Nel post precedente, abbiamo esaminato il processo di rendering e illustrato il compositore. In questo post, vediamo come il compositore abilita un'interazione fluida quando arriva l'input dell'utente.
Inserisci gli eventi dal punto di vista del browser
Quando senti "eventi di input" potresti pensare solo a una digitazione nella casella di testo o al clic del mouse, ma dal punto di vista del browser, per input si intende qualsiasi gesto dell'utente. Lo scorrimento della rotellina del mouse è un input e tocco o mouseover sono anch'essi un evento di input.
Quando si verifica un gesto dell'utente, ad esempio il tocco su uno schermo, il processo del browser è quello che riceve
. Tuttavia, il processo del browser è a conoscenza solo di dove si è verificato il gesto dal
i contenuti all'interno di una scheda sono gestiti dal processo del renderer. Quindi il processo del browser invia l'evento
(come touchstart
) e le relative coordinate al processo del renderer. Il processo del renderer gestisce
in modo appropriato individuando la destinazione dell'evento ed eseguendo i listener di eventi collegati.
Il compositore riceve eventi di input
Nel post precedente abbiamo visto in che modo il compositore poteva gestire facilmente lo scorrimento rasterizzati. Se alla pagina non sono collegati listener di eventi di input, il thread del compositore può creano un nuovo frame composito completamente indipendente dal thread principale. Ma cosa succede se un evento sono stati collegati alla pagina? Come farebbe il thread del compositore a scoprire se l'evento ha bisogno da gestire?
Informazioni sulle regioni non scorrevoli velocemente
Poiché l'esecuzione di JavaScript è il job del thread principale, quando una pagina viene composita, il thread del compositore contrassegna una regione della pagina a cui sono collegati gestori di eventi come "Non-Fast Scorriable Region". Di con queste informazioni, il thread del compositore può assicurarsi di inviare l'evento di input al thread principale se l'evento si verifica in quella regione. Se l'evento di input proviene dall'esterno di questa regione, il thread del compositore prosegue la composizione di un nuovo frame senza attendere il thread principale.
Presta attenzione quando scrivi gestori di eventi
Un modello di gestione degli eventi comune nello sviluppo web è la delega degli eventi. Dal fumetto degli eventi, è possibile collegare un gestore di eventi all'elemento più in alto e delegare le attività in base al target dell'evento. Tu potrebbe aver visto o scritto un codice simile al seguente.
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault();
}
});
Dato che devi scrivere un solo gestore di eventi per tutti gli elementi, l'ergonomia di questo evento modelli di delega sono allettanti. Tuttavia, se esamini questo codice dal punto di vista del browser, , ora l'intera pagina viene contrassegnata come area non scorrevole velocemente. Ciò significa che anche se dell'applicazione non si preoccupa dell'input da alcune parti della pagina, il thread del compositore deve comunicano con il thread principale e attendono che avvenga ogni volta che arriva un evento di input. Di conseguenza, non è sufficiente scorrere la capacità di scorrimento fluida del compositore.
Per evitare che ciò accada, puoi ignorare passive: true
opzioni per il tuo evento
e ascolto. Questo suggerisce al browser che vuoi ancora ascoltare l'evento nel thread principale.
ma può anche comporre un nuovo frame.
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault()
}
}, {passive: true});
Verificare se l'evento è annullabile
Supponi di avere una casella in una pagina che vuoi limitare alla sola scorrimento orizzontale.
Se utilizzi l'opzione passive: true
nell'evento del puntatore, lo scorrimento della pagina può essere fluido, ma
lo scorrimento verticale potrebbe essere iniziato nel momento in cui vuoi preventDefault
per limitare
direzione di scorrimento. Puoi verificarlo utilizzando il metodo 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});
In alternativa, puoi utilizzare una regola CSS come touch-action
per eliminare completamente il gestore di eventi.
#area {
touch-action: pan-x;
}
Individuazione del target dell'evento
Quando il thread del compositore invia un evento di input al thread principale, la prima cosa da eseguire è un hit per trovare il target dell'evento. Hit test utilizza i dati dei record di colorazione generati durante il rendering per scoprire cosa c'è sotto le coordinate del punto in cui si è verificato l'evento.
Ridurre al minimo gli invii di eventi al thread principale
Nel post precedente abbiamo parlato di come il nostro tipico display aggiorna lo schermo 60 volte al secondo. come dobbiamo stare al passo con la cadenza per un'animazione fluida. Per l'input, un tipico touch-screen un dispositivo invia un evento touch 60-120 volte al secondo, mentre un mouse standard invia gli eventi 100 volte secondo. L'evento di input ha una fedeltà maggiore di quella che lo schermo può aggiornare.
Se un evento continuo come touchmove
è stato inviato al thread principale 120 volte al secondo,
potrebbe attivare una quantità eccessiva di hit test ed esecuzione di JavaScript rispetto alla lentezza
la schermata può aggiornarsi.
Per ridurre al minimo le chiamate eccessive al thread principale, Chrome unisce eventi continui (ad esempio
wheel
, mousewheel
, mousemove
, pointermove
, touchmove
) e ritardi nelle spedizioni fino al giorno
subito prima del prossimo requestAnimationFrame
.
Qualsiasi evento discreto come keydown
, keyup
, mouseup
, mousedown
, touchstart
e touchend
vengono spediti immediatamente.
Usa getCoalescedEvents
per ottenere eventi intra-frame
Per la maggior parte delle applicazioni web, gli eventi combinati dovrebbero essere sufficienti per offrire una buona esperienza utente.
Tuttavia, se stai creando cose come disegnare un'applicazione e inserire un percorso basato su
touchmove
, potresti perdere le coordinate tra un'area e l'altra per tracciare una linea smussata. In questo caso,
puoi utilizzare il metodo getCoalescedEvents
nell'evento puntatore per ottenere informazioni su questi
eventi uniti.
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.
}
});
Passaggi successivi
In questa serie, abbiamo illustrato il funzionamento interno di un browser web. Se non hai mai pensato al perché
DevTools consiglia di aggiungere {passive: true}
al gestore di eventi o perché potresti scrivere async
nel tag di script, mi auguro che questa serie abbia fatto luce sul motivo per cui un browser ha bisogno di tali
per fornire un'esperienza web più rapida e fluida.
Usa Lighthouse
Se vuoi rendere il tuo codice compatibile con il browser ma non sai da dove iniziare, Lighthouse è uno strumento che esegue il controllo di qualsiasi sito web e ti offre una creare report su ciò che viene fatto corretto e su ciò che va migliorato. Leggere l'elenco dei controlli ti dà anche un'idea delle cose che interessano a un browser.
Scopri come misurare il rendimento
Le modifiche al rendimento possono variare in base al sito, è quindi fondamentale misurare il rendimento del tuo sito e decidere cosa si adatta meglio al tuo sito. Il team di Chrome DevTools ha alcuni tutorial come misurare il rendimento del tuo sito.
Aggiungi norme sulle funzionalità al tuo sito
Se vuoi fare un ulteriore passaggio, Criteri relativi alle funzionalità è una nuova
una funzionalità della piattaforma web che può fungere da barriera per te durante la realizzazione del tuo progetto. Attivazione in corso...
le norme relative alle funzionalità garantiscono il determinato comportamento della tua app e ti impediscono di commettere errori.
Ad esempio, se vuoi assicurarti che la tua app non blocchi mai l'analisi, puoi eseguirla
il criterio per gli script sincroni. Quando la funzionalità sync-script: 'none'
è abilitata, il codice JavaScript che blocca i parser
l'esecuzione del modello. In questo modo il parser impedisce a qualsiasi codice di bloccare l'analizzatore sintattico.
non devi preoccuparti di mettere in pausa l'analizzatore sintattico.
Conclusione
Quando ho iniziato a creare siti web, mi interessava quasi solo come scrivere il mio codice e cosa mi aiuterebbero a essere più produttivo. Queste cose sono importanti, ma dobbiamo anche pensare a come un browser accetta il codice che scriviamo. I browser moderni hanno investito e continuano a investire in modi per offrire una migliore esperienza web agli utenti. Essere gentili con il browser organizzando il nostro codice, migliora l'esperienza utente. Spero che vorrai unirti a me nella missione di essere gentile con i browser.
Un enorme ringraziamento a tutti coloro che hanno recensito le prime bozze di questa serie, incluse, a titolo esemplificativo, a): Alex Russell, Paul irlandese, Meggin Kearney Eric Bidelman Mathias Bynens, Addy Osmani, Kinuko Yasuda, Nasko Oskov, e Charlie Reis.
Ti è piaciuta questa serie? Se hai domande o suggerimenti per il prossimo post, Vorrei conoscere la tua opinione nella sezione dei commenti qui sotto o @kosamari su Twitter.