Um die Leistung beim Scrollen/Zoomen von wheel
zu verbessern, sollten Entwickler die Ereignis-Listener wheel
und mousewheel
als passiv registrieren. Dazu übergeben Sie die Option {passive: true}
an addEventListener()
. Wenn Sie die Event-Listener als passiv registrieren, teilen Sie dem Browser mit, dass die Rad-Listener preventDefault()
nicht aufrufen und der Browser gefahrlos scrollen und zoomen kann, ohne die Listener zu blockieren.
Das Problem besteht darin, dass die Wheel-Event-Listener meist passiv sind (nicht preventDefault()
aufrufen), aber nicht explizit als solches angegeben sind. Der Browser muss also warten, bis die Verarbeitung des JS-Ereignisses abgeschlossen ist, bevor das Scrollen oder Zoomen gestartet wird, auch wenn das Warten nicht notwendig ist. In Chrome 56 haben wir dieses Problem für touchstart
und touchmove
behoben, das später von Safari und Firefox übernommen wurde. Wie Sie dem damaligen Demonstrationsvideo entnehmen können, wurde das Verhalten bei der Scroll-Antwort merklich verzögert. In Chrome 73 haben wir die gleiche Maßnahme auf wheel
- und mousewheel
-Ereignisse angewendet.
Die Intervention
Mit dieser Änderung möchten wir die Zeit für die Aktualisierung des Displays verkürzen, nachdem der Nutzer mit dem Scrollen mit dem Rad oder Touchpad begonnen hat, ohne dass Entwickler Code ändern müssen. Unsere Messwerte zeigen, dass 75% der Event-Listener wheel
und mousewheel
, die auf Root-Zielen (Fenster, Dokument oder Textkörper) registriert sind, keine Werte für die passive Option angeben und mehr als 98% dieser Listener nicht auf preventDefault()
aufrufen. In Chrome 73 ändern wir die wheel
- und mousewheel
-Listener, die auf Root-Zielen (Fenster, Dokument oder Textkörper) registriert sind, standardmäßig passiv. Das bedeutet, dass ein Event-Listener wie
window.addEventListener("wheel", func);
entspricht:
window.addEventListener("wheel", func, {passive: true});
Wenn preventDefault()
im Listener aufgerufen wird, wird die folgende Warnung in den Entwicklertools ignoriert:
[Intervention] Unable to preventDefault inside passive event listener due
to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312
Fehler und Anleitung
In den meisten Fällen wird kein Fehler festgestellt. In seltenen Fällen (laut unseren Messwerten bei weniger als 0,3% der Seiten) kann es zu unbeabsichtigtem Scrollen oder Zoomen kommen, weil der preventDefault()
-Aufruf in den standardmäßig als passiv behandelten Listenern ignoriert wird. Ihre Anwendung kann feststellen, ob dies überhaupt passiert ist. Dazu wird geprüft, ob der Aufruf von preventDefault()
über das Attribut defaultPrevented
Auswirkungen 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 Event-Listener so einzustellen, dass er blockiert wird.