Schnelles Scrollen des Mausrads standardmäßig

Sahel Sharify
Sahel Sharify

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.