Scorrimento rapido con la rotellina per impostazione predefinita

Sahel Sharify
Sahel Sharify

Per migliorare le prestazioni di scorrimento/zoom di wheel, gli sviluppatori sono invitati a registrare i listener di eventi wheel e mousewheel come passivi passando l'opzione {passive: true} a addEventListener(). La registrazione degli ascoltatori di eventi come passivi indica al browser che gli ascoltatori della rotellina non chiameranno preventDefault() e che il browser può eseguire in sicurezza lo scorrimento e lo zoom senza bloccarsi sugli ascoltatori.

Il problema è che, il più delle volte, gli ascoltatori di eventi relativi alla rotella del mouse sono concettualmente passivi (non chiamano preventDefault()), ma non sono specificati esplicitamente come tali, il che richiede al browser di attendere il completamento della gestione degli eventi JS prima di iniziare a scorrere/aumentare lo zoom, anche se l'attesa non è necessaria. In Chrome 56, abbiamo risolto questo problema per touchstart e touchmove, e questa modifica è stata successivamente adottata sia da Safari che da Firefox. Come puoi vedere dal video dimostrativo che abbiamo realizzato in quel momento, lasciare invariato il comportamento ha prodotto un ritardo notevole nella risposta allo scorrimento. Ora in Chrome 73 abbiamo applicato lo stesso intervento agli eventi wheel e mousewheel.

The Intervention

Il nostro obiettivo con questa modifica è ridurre il tempo necessario per aggiornare il display dopo che l'utente inizia a scorrere con la rotellina o il touchpad senza che gli sviluppatori debbano modificare il codice. Le nostre metriche mostrano che il 75% degli ascoltatori di eventi wheel e mousewheel registrati su target principali (window, document o body) non specifica alcun valore per l'opzione passiva e oltre il 98% di questi ascoltatori non chiama preventDefault(). In Chrome 73, stiamo modificando gli ascoltatori wheel e mousewheel registrati sui target principali (window, document o body) in modo che siano passivi per impostazione predefinita. Ciò significa che un listener di eventi come:

window.addEventListener("wheel", func);

diventa equivalente a:

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

Inoltre, la chiamata a preventDefault() all'interno dell'ascoltatore verrà ignorata con il seguente avviso di DevTools:

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

Guasti e indicazioni

Nella maggior parte dei casi, non verrà rilevata alcuna interruzione. Solo in rari casi (meno dello 0,3% delle pagine in base alle nostre metriche), potrebbe verificarsi scorrimento/zoom involontario a causa dell'ignoranza della chiamata preventDefault() all'interno degli ascoltatori trattati come passivi per impostazione predefinita. La tua applicazione può determinare se potrebbe verificarsi questo problema in produzione controllando se la chiamata a preventDefault() ha avuto un effetto tramite la proprietà defaultPrevented. La correzione per le richieste interessate è relativamente semplice: passa {passive: false} a addEventListener() per ignorare il comportamento predefinito e mantenere l'ascoltatore di eventi come bloccante.