Wir wissen, dass die Scrollgeschwindigkeit für die Interaktion von Nutzern mit einer Website auf Mobilgeräten entscheidend ist. Touch-Ereignis-Listener verursachen jedoch häufig erhebliche Probleme mit der Scrollleistung. In Chrome können Touch-Ereignis-Listener passiv sein ({passive: true}
an addEventListener()
übergeben) und die Pointer Events API wird unterstützt.
Das sind großartige Funktionen, um neue Inhalte in Modelle einzubinden, die das Scrollen nicht blockieren. Für Entwickler sind sie jedoch manchmal schwer zu verstehen und zu implementieren.
Wir sind der Meinung, dass das Web standardmäßig schnell sein sollte, ohne dass Entwickler esoterische Details zum Browserverhalten kennen müssen. In Chrome 56 sind Touch-Listener standardmäßig passiv, wenn dies am ehesten der Absicht des Entwicklers entspricht. Wir sind davon überzeugt, dass wir so die Nutzerfreundlichkeit erheblich verbessern und gleichzeitig die negativen Auswirkungen auf Websites minimieren können.
In seltenen Fällen kann diese Änderung zu unerwünschtem Scrollen führen. Das lässt sich in der Regel ganz einfach beheben, indem Sie dem Element, in dem nicht gescrollt werden soll, den Stil touch-action: none zuweisen. Im Folgenden finden Sie weitere Informationen dazu, wie Sie feststellen können, ob Sie betroffen sind, und was Sie dagegen tun können.
Hintergrund: Abbrechenbare Ereignisse verlangsamen Ihre Seite
Wenn du preventDefault() in den touchstart
- oder ersten touchmove
-Ereignissen aufrufst, wird das Scrollen verhindert.
Das Problem ist, dass Listener in den meisten Fällen preventDefault()
nicht aufrufen. Der Browser muss jedoch warten, bis das Ereignis abgeschlossen ist, um sich sicher zu sein.
Hier helfen vom Entwickler definierte „passive Ereignis-Listener“. Wenn Sie ein Touch-Ereignis mit einem {passive: true}
-Objekt als dritten Parameter in Ihren Ereignishandler einfügen, teilen Sie dem Browser mit, dass der touchstart
-Listener preventDefault()
nicht aufruft. Der Browser kann dann das Scrollen sicher ausführen, ohne den Listener zu blockieren. Beispiel:
window.addEventListener("touchstart", func, {passive: true} );
Die Intervention
Unser Hauptziel besteht darin, die Zeit zu verkürzen, die für die Aktualisierung des Displays nach dem Berühren des Displays durch den Nutzer benötigt wird. Um die Verwendung von „touchstart“ und „touchmove“ besser nachvollziehen zu können, haben wir Messwerte hinzugefügt, mit denen ermittelt wird, wie oft das Scrollen blockiert wurde.
Wir haben den Prozentsatz der abwählbaren Touch-Ereignisse untersucht, die an ein Stammziel (Fenster, Dokument oder Body) gesendet wurden. Dabei haben wir festgestellt, dass etwa 80% dieser Listener konzeptionell passiv sind, aber nicht als solche registriert wurden. Angesichts der Größe dieses Problems haben wir erkannt, dass wir das Scrollen ohne Entwicklereingriff verbessern können, indem wir diese Ereignisse automatisch als „passiv“ kennzeichnen.
Daher haben wir unsere Intervention so definiert: Wenn das Ziel eines Touchstart- oder Touchmove-Listeners window
, document
oder body
ist, wird passive
standardmäßig auf true
gesetzt. Das bedeutet, dass Code wie der folgende nicht mehr funktioniert:
window.addEventListener("touchstart", func);
wird zu:
window.addEventListener("touchstart", func, {passive: true} );
Aufrufe von preventDefault()
innerhalb des Listeners werden jetzt ignoriert.
Im folgenden Diagramm sehen Sie, wie lange die 1% der längsten Scrollvorgänge gedauert haben, vom Zeitpunkt, an dem der Nutzer den Bildschirm berührt hat, um zu scrollen, bis zum Zeitpunkt, an dem das Display aktualisiert wurde. Diese Daten beziehen sich auf alle Websites in Chrome für Android. Vor der Optimierung dauerte ein Prozent der Scrollvorgänge etwas mehr als 400 ms. In Chrome 56 Beta wurde sie jetzt auf etwas mehr als 250 ms reduziert – eine Verringerung um etwa 38%. Künftig soll „passive“ standardmäßig für alle touchstart
- und touchmove
-Zuhörer aktiviert sein, um die Latenz auf unter 50 ms zu senken.

Fehlerbehebung und Anleitung
In den allermeisten Fällen kommt es nicht zu einem Bruch. Wenn es jedoch zu einem Fehler kommt, ist das häufigste Symptom, dass das Scrollen unerwünscht erfolgt. In seltenen Fällen können Entwickler auch unerwartete Klick-Ereignisse feststellen, wenn preventDefault()
in einem touchend
-Listener fehlt.
In Chrome 56 und höher wird in den DevTools eine Warnung protokolliert, wenn Sie preventDefault()
in einem Ereignis aufrufen, bei dem die Intervention aktiv ist.
touch-passive.html:19 Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080
Ihre Anwendung kann feststellen, ob dieses Problem in der Praxis auftritt, indem sie über die Eigenschaft defaultPrevented
prüft, ob der Aufruf von preventDefault
eine Auswirkung hatte.
Wir haben festgestellt, dass die meisten betroffenen Seiten relativ einfach korrigiert werden können, indem Sie nach Möglichkeit die CSS-Eigenschaft touch-action anwenden. Wenn Sie das Scrollen und Zoomen im Browser innerhalb eines Elements verhindern möchten, wenden Sie touch-action: none
darauf an. Wenn Sie ein horizontales Karussell haben, sollten Sie touch-action: pan-y pinch-zoom
darauf anwenden, damit Nutzer wie gewohnt vertikal scrollen und zoomen können. Die korrekte Anwendung von Touch-Aktionen ist bereits in Browsern wie Edge für Computer erforderlich, die Pointer-Ereignisse und keine Touch-Ereignisse unterstützen. Für Safari auf Mobilgeräten und ältere mobile Browser, die Touch-Aktionen nicht unterstützen, müssen Ihre Touch-Listener weiterhin preventDefault
aufrufen, auch wenn diese Aktion von Chrome ignoriert wird.
In komplexeren Fällen kann es auch erforderlich sein, eine der folgenden Methoden zu verwenden:
- Wenn Ihr
touchstart
-ListenerpreventDefault()
aufruft, muss preventDefault() auch von den zugehörigen Touchend-Listenern aufgerufen werden, um weiterhin die Generierung von Klickereignissen und anderen Standard-Tippen-Verhalten zu unterdrücken. - Als letzten (und nicht empfohlenen) Schritt können Sie
{passive: false}
an addEventListener() übergeben, um das Standardverhalten zu überschreiben. Du musst prüfen, ob der User-Agent EventListenerOptions unterstützt.
Fazit
In Chrome 56 beginnt das Scrollen auf vielen Websites wesentlich schneller. Das ist die einzige Auswirkung, die die meisten Entwickler durch diese Änderung bemerken werden. In einigen Fällen stellen Entwickler möglicherweise unbeabsichtigtes Scrollen fest.
Für Safari auf Mobilgeräten ist dies zwar weiterhin erforderlich, Websites sollten jedoch nicht darauf angewiesen sein, preventDefault()
in touchstart
- und touchmove
-Listenern aufzurufen, da dies in Chrome nicht mehr garantiert wird. Entwickler sollten die CSS-Eigenschaft touch-action
auf Elemente anwenden, bei denen Scrollen und Zoomen deaktiviert werden sollen, um den Browser zu benachrichtigen, bevor Touch-Ereignisse auftreten.
Wenn Sie das Standardverhalten eines Tippens unterdrücken möchten (z. B. die Generierung eines Klickereignisses), rufen Sie preventDefault()
in einem touchend
-Listener auf.