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 in Eingabe-Handlern keine Stiländerungen 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 kann der Compositor-Thread der Seite, wenn ein Nutzer mit der Seite interagiert, die Touch-Eingabe des Nutzers verarbeiten und den Inhalt einfach verschieben. Das 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 dieser Handler fertig ausgeführt wurde, da Sie preventDefault() aufrufen und das Scrollen per Touch unterbrechen können. Auch wenn Sie preventDefault() nicht aufrufen, muss der Renderer warten. Das Scrollen des Nutzers wird daher 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 rechenintensiven Code blockieren.