Scorrimento rapido con la rotellina per impostazione predefinita

Sahel Sharify
Sahel Sharify

Per migliorare le prestazioni dello scorrimento e dello 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 dei listener di eventi come passivi indica al browser che i listener a rotelle non chiameranno preventDefault() e il browser può eseguire lo scorrimento e lo zoom in sicurezza senza bloccare i listener.

Il problema è che molto spesso i listener di eventi wheel sono concettualmente passivi (non chiamare preventDefault()), ma non sono esplicitamente specificati come tali e richiedono al browser di attendere il completamento della gestione degli eventi JS prima di iniziare a scorrere/eseguire lo zoom anche se l'attesa non è necessaria. In Chrome 56, abbiamo risolto il problema per touchstart e touchmove e la modifica è stata successivamente adottata sia da Safari sia da Firefox. Come puoi vedere dal video dimostrativo che abbiamo realizzato in quel momento, questo lascia il comportamento come si è verificato un notevole ritardo nella risposta di scorrimento. Ora in Chrome 73 abbiamo applicato lo stesso intervento agli eventi wheel e mousewheel.

L'intervento

Il nostro obiettivo con questa modifica è ridurre il tempo necessario per aggiornare il display dopo che l'utente ha iniziato a scorrere con la rotellina o con 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 nei target principali (finestra, documento o corpo) non specifica alcun valore per l'opzione passiva e più del 98% di questi ascoltatori non chiama preventDefault(). In Chrome 73, modificheremo i listener wheel e mousewheel registrati sulle destinazioni principali (finestra, documento o corpo) in modo che siano passivi per impostazione predefinita. 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 del listener verrà ignorata con il seguente avviso DevTools:

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

Interruzione e guida

Nella stragrande maggioranza dei casi non si verificano interruzioni. Solo in rari casi (meno dello 0,3% delle pagine secondo le nostre metriche), lo scorrimento/lo zoom involontario potrebbe verificarsi a causa del fatto che la chiamata preventDefault() viene ignorata all'interno degli ascoltatori che sono trattati come passivi per impostazione predefinita. L'applicazione può determinare se sta raggiungendo questo problema controllando se la chiamata a preventDefault() ha avuto effetto tramite la proprietà defaultPrevented. La soluzione per i casi interessati è relativamente facile: passa {passive: false} a addEventListener() per ignorare il comportamento predefinito e mantenere l'ascoltatore eventi come blocco.