Um die wheel
-Scroll-/Zoomleistung zu verbessern, sollten Entwickler wheel
- und mousewheel
-Ereignis-Listener als passiv registrieren, indem sie die Option {passive: true}
an addEventListener()
übergeben. Wenn Sie die Ereignis-Listener als passiv registrieren, wird dem Browser mitgeteilt, dass die Listener für das Scrollrad preventDefault()
nicht aufrufen. Der Browser kann dann sicher scrollen und zoomen, ohne die Listener zu blockieren.
Das Problem ist, dass die Wheel-Ereignis-Listener in den meisten Fällen konzeptionell passiv sind (preventDefault()
wird nicht aufgerufen), aber nicht explizit als solche angegeben werden. Daher muss der Browser warten, bis die JS-Ereignisbehandlung abgeschlossen ist, bevor er mit dem Scrollen/Zoomen beginnt, obwohl dies nicht erforderlich ist. In Chrome 56 haben wir dieses Problem für touchstart
und touchmove
behoben. Diese Änderung wurde später sowohl in Safari als auch in Firefox übernommen. Wie Sie in dem Demonstrationsvideo sehen können, das wir damals erstellt haben, führte das Beibehalten des ursprünglichen Verhaltens zu einer deutlichen Verzögerung bei der Scrollreaktion. In Chrome 73 haben wir diese Maßnahme auf wheel
- und mousewheel
-Ereignisse ausgeweitet.
Die Intervention
Mit dieser Änderung soll die Zeit verkürzt werden, die vergeht, bis das Display aktualisiert wird, nachdem der Nutzer mit dem Scrollrad oder dem Touchpad zu scrollen begonnen hat, ohne dass Entwickler Code ändern müssen. Unsere Messwerte zeigen, dass 75% der wheel
- und mousewheel
-Ereignis-Listener, die auf Stammzielen (Fenster, Dokument oder Body) registriert sind, keine Werte für die passive Option angeben und mehr als 98% dieser Listener preventDefault()
nicht aufrufen. In Chrome 73 werden die wheel
- und mousewheel
-Listener, die für Stammziele (window, document oder body) registriert sind, standardmäßig inaktiv. Das bedeutet, dass ein Event-Listener wie
window.addEventListener("wheel", func);
wird zu:
window.addEventListener("wheel", func, {passive: true});
Der Aufruf von preventDefault()
innerhalb des Listeners wird ignoriert und es wird die folgende Warnung in den Entwicklertools angezeigt:
[Intervention] Unable to preventDefault inside passive event listener due
to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312
Fehlerbehebung und Anleitung
In den allermeisten Fällen kommt es nicht zu einem Bruch. Nur in seltenen Fällen (laut unseren Messwerten auf weniger als 0,3% der Seiten) kann es zu unbeabsichtigtem Scrollen oder Zoomen kommen, weil der preventDefault()
-Aufruf in den Listenern ignoriert wird, die standardmäßig als passiv behandelt werden. Ihre Anwendung kann feststellen, ob dieses Problem in der Praxis auftritt, indem sie über das Attribut defaultPrevented
prüft, ob der Aufruf von preventDefault()
eine Auswirkung hatte. Die Lösung für die betroffenen Fälle ist relativ einfach: Übergeben Sie {passive: false}
an addEventListener()
, um das Standardverhalten zu überschreiben und den Ereignis-Listener als blockierend zu belassen.