Eingabe-Handler entprellen

Eingabehandler können eine potenzielle Ursache für Leistungsprobleme in Ihren Apps sein, da sie die Vervollständigung von Frames blockieren und zusätzliche und unnötige Layoutarbeiten verursachen können.

Paul Lewis

Eingabehandler können eine potenzielle Ursache für Leistungsprobleme in Ihren Apps sein, da sie die Vervollständigung von Frames blockieren und zusätzliche und unnötige Layoutarbeiten verursachen können.

Zusammenfassung

  • Vermeiden Sie lange laufende Eingabehandler, da sie das Scrollen blockieren können.
  • Nehmen Sie in Eingabehandlern keine Stiländerungen vor.
  • Entprellen Sie Ihre Handler. Speichern Sie Ereigniswerte und behandeln Sie Stiländerungen im nächsten requestAnimationFrame-Callback.

Lange laufende Eingabehandler vermeiden

Im schnellsten Fall kann der Compositor-Thread der Seite die Touch-Eingabe des Nutzers aufnehmen und den Inhalt einfach verschieben, wenn ein Nutzer mit der Seite interagiert. Dazu ist keine Arbeit durch den Hauptthread erforderlich, in dem JavaScript, Layout, Stile oder Paint ausgeführt werden.

Leichtes Scrollen: Die Verzögerung zwischen der Berührung durch den Nutzer und dem GPU-Commit ist minimal, da nur der Compositor verwendet wird.

Wenn Sie jedoch einen Eingabehandler wie touchstart, touchmove oder touchend anhängen, muss der Compositor-Thread warten, bis dieser Handler ausgeführt wurde, da Sie möglicherweise preventDefault() aufrufen und verhindern, dass der Touch-Scroll ausgeführt wird. Auch wenn Sie preventDefault() nicht aufrufen, muss der Compositor warten. Daher wird das Scrollen des Nutzers blockiert, was zu Ruckeln und fehlenden Frames führen kann.

Starkes Scrollen: Nach der Berührung durch den Nutzer wird das Scrollen blockiert und der GPU-Commit wird durch den „onTouchMove“-Handler verzögert.

Kurz gesagt: Alle von Ihnen ausgeführten Eingabehandler sollten schnell ausgeführt werden und dem Compositor die Arbeit ermöglichen.

Stiländerungen in Eingabehandlern vermeiden

Eingabehandler wie Scroll- und Touch-Handler werden so geplant, dass sie direkt vor allen requestAnimationFrame-Callbacks ausgeführt werden.

Wenn Sie in einem dieser Handler eine visuelle Änderung vornehmen, sind zu Beginn von requestAnimationFrame Stiländerungen ausstehend. Wenn Sie dann visuelle Eigenschaften zu Beginn des requestAnimationFrame-Callbacks lesen, wie im Abschnitt „Große, komplexe Layouts und Layout-Thrashing vermeiden“ empfohlen, lösen Sie ein erzwungenes synchrones Layout aus.

Starkes Scrollen; der Planungsstil wird nach „requestAnimationFrame“ gelesen, was zu einem erzwungenen synchronen Layout führt.

Scroll-Handler entprellen

Die Lösung für beide oben genannten Probleme ist dieselbe: Sie sollten visuelle Änderungen immer auf den nächsten requestAnimationFrame-Callback entprellen:

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);

Das hat auch den zusätzlichen Vorteil, dass Ihre Eingabehandler leicht bleiben. So blockieren Sie keine rechenintensiven Codevorgänge wie Scrollen oder Touch.