Eingabe-Handler entprellen

Eingabe-Handler können eine potenzielle Ursache für Leistungsprobleme in Ihren Apps sein, da sie das Ausführen von Frames blockieren und zusätzliche und unnötige Layoutarbeiten verursachen können.

Paul Lewis

Eingabe-Handler können eine potenzielle Ursache für Leistungsprobleme in Ihren Apps sein, da sie das Ausführen von Frames blockieren und zusätzliche und unnötige Layoutarbeiten verursachen können.

Zusammenfassung

  • Vermeiden Sie lang laufende Eingabe-Handler, da sie das Scrollen blockieren können.
  • Nehmen Sie keine Stiländerungen in Eingabehandlern vor.
  • Debouncen Sie Ihre Handler, speichern Sie Ereigniswerte und verarbeiten Sie Stiländerungen im nächsten requestAnimationFrame-Callback.

Lange laufende Eingabe-Handler vermeiden

Im schnellstmöglichen Fall, wenn ein Nutzer mit der Seite interagiert, kann der Compositor-Thread der Seite die Touch-Eingabe des Nutzers übernehmen und den Inhalt einfach verschieben. Dies erfordert keine Arbeit des Haupt-Threads, in dem JavaScript, Layout, Stile oder Malen ausgeführt werden.

Leichtes Scrollen; nur Compositor.

Wenn Sie jedoch einen Eingabe-Handler wie touchstart, touchmove oder touchend anhängen, muss der Compositor-Thread warten, bis die Ausführung dieses Handlers abgeschlossen ist, da Sie preventDefault() aufrufen und das Scrollen per Touch unterbrechen können. Auch wenn Sie preventDefault() nicht aufrufen, muss der Compositor warten. Das Scrollen des Nutzers wird dadurch blockiert, was zu Rucklern und fehlenden Frames führen kann.

Ruckeliges Scrollen; der Compositor ist für JavaScript blockiert.

Kurz gesagt: Sie sollten dafür sorgen, dass alle von Ihnen ausgeführten Eingabe-Handler schnell ausgeführt werden und dem Compositor die Möglichkeit geben, seine Arbeit zu erledigen.

Stiländerungen in Eingabe-Handlern vermeiden

Eingabe-Handler wie die für Scrollen und Berühren werden kurz vor allen requestAnimationFrame-Callbacks ausgeführt.

Wenn Sie in einem dieser Handlers eine visuelle Änderung vornehmen, werden zu Beginn der requestAnimationFrame ausstehende Stiländerungen angezeigt. Wenn Sie dann visuelle Eigenschaften zu Beginn des requestAnimationFrame-Callbacks lesen, wie in der Empfehlung unter Große, komplexe Layouts und Layout-Trashing vermeiden vorgeschlagen, lösen Sie ein erzwungenes synchrones Layout aus.

Ruckeliges Scrollen; der Compositor ist für JavaScript blockiert.

Scroll-Handler entkoppeln

Die Lösung für beide Probleme ist dieselbe: Visuelle Änderungen sollten immer bis zum nächsten requestAnimationFrame-Callback verzögert werden:

function onScroll (evt) {

    // Store the scroll value for laterz.
    lastScrollY = window.scrollY;

    // Prevent multiple rAF callbacks.
    if (scheduledAnimationFrame)
    return;

    scheduledAnimationFrame = true;
    requestAnimationFrame(readAndUpdatePage);
}

window.addEventListener('scroll', onScroll);

Außerdem haben Sie so den Vorteil, dass Ihre Eingabe-Handler schlanker bleiben. Das ist großartig, weil Sie jetzt keine Dinge wie Scrollen oder Touch-Ereignisse durch rechenswüstigen Code blockieren.