Uno sguardo all'interno del browser web moderno (parte 4)

Mariko Kosaka

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.

evento di input
. Figura 1: evento di input indirizzato attraverso il processo del browser al processo del renderer

Il compositore riceve eventi di input

Figura 2: area visibile con passaggio del mouse sopra i livelli di pagina

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.

regione limitata non scorrevole veloce
. Figura 3: diagramma dell'input descritto per la regione a scorrimento non rapido

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.

regione non scorrevole a pagina intera
. Figura 4: diagramma dell'input descritto nell'area a scorrimento non rapido che copre un'intera pagina

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

scorrimento pagina
. Figura 5: una pagina web con parte della pagina fissata su uno scorrimento orizzontale

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

hit test
. Figura 6: il filo conduttore principale che guarda i record del dipinto chiede cosa è stato disegnato sul punto x.y

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.

eventi non filtrati
. Figura 7: eventi che inondano la sequenza temporale del frame, causando il blocco della pagina

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.

eventi uniti
. Figura 8: stessa sequenza temporale di prima, ma l'evento viene unito e ritardato

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.

getCoalescedEvents
. Figura 9: percorso fluido al tocco a sinistra, percorso limitato accorpato a destra
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

grazie

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.