Warum sind manche Animationen langsam?

In modernen Browsern können zwei CSS-Properties kostengünstig animiert werden: transform und opacity. Wenn Sie etwas anderes animieren, erreichen Sie wahrscheinlich nicht die flüssigen 60 Bilder pro Sekunde (FPS). In diesem Beitrag wird erklärt, warum das so ist.

Es ist allgemein anerkannt, dass eine Framerate von 60 fps das Ziel ist, wenn im Web animiert wird. Mit dieser Framerate sehen Ihre Animationen flüssig aus. Im Web ist ein Frame die Zeit, die für die Aktualisierung und Neumalerei des Bildschirms erforderlich ist. Wenn jeder Frame nicht innerhalb von 16,7 ms (1.000 ms ÷ 60 ≈ 16,7) fertiggestellt wird, nehmen Nutzer die Verzögerung wahr.

Die Rendering-Pipeline

Damit etwas auf einer Webseite angezeigt werden kann, muss der Browser die folgenden Schritte ausführen:

  1. Stil: Hier werden die Stile berechnet, die auf die Elemente angewendet werden.
  2. Layout: Hier werden die Geometrie und die Position für jedes Element generiert.
  3. Paint: Hiermit werden die Pixel für jedes Element ausgefüllt.
  4. Composite: Die Elemente in Ebenen unterteilen und die Ebenen auf dem Bildschirm zeichnen.

Diese vier Schritte werden als Rendering-Pipeline des Browsers bezeichnet.

Wenn Sie etwas auf einer Seite animieren, die bereits geladen wurde, müssen diese Schritte noch einmal ausgeführt werden. Dieser Vorgang beginnt mit dem Schritt, der geändert werden muss, damit die Animation ausgeführt werden kann.

Wie bereits erwähnt, sind diese Schritte abfolgeabhängig. Wenn Sie beispielsweise etwas animieren, das das Layout ändert, müssen auch die Schritte „Paint“ und „Composite“ noch einmal ausgeführt werden. Die Animation von etwas, das das Layout ändert, ist daher teurer als die Animation von etwas, das nur die Komposition ändert.

Layouteigenschaften animieren

Bei Layoutänderungen wird die Geometrie (Position und Größe) aller Elemente berechnet, die von der Änderung betroffen sind. Wenn Sie ein Element ändern, muss die Geometrie anderer Elemente möglicherweise neu berechnet werden. Wenn Sie beispielsweise die Breite des <html>-Elements ändern, kann sich das auf eines seiner untergeordneten Elemente auswirken. Da Elemente überlaufen und sich gegenseitig beeinflussen, können Änderungen weiter unten im Stammbaum manchmal zu Layoutberechnungen bis ganz oben führen.

Je größer der Baum der sichtbaren Elemente ist, desto länger dauert es, die Layoutberechnungen durchzuführen.

Maleigenschaften animieren

Bei der Paint-Phase wird festgelegt, in welcher Reihenfolge Elemente auf dem Bildschirm dargestellt werden sollen. Sie ist oft die am längsten laufende Aufgabe in der Pipeline.

Der Großteil der Darstellung in modernen Browsern erfolgt in Software-Rasterizern. Je nachdem, wie die Elemente in Ihrer App in Ebenen gruppiert sind, müssen möglicherweise auch andere Elemente als das geänderte neu gemalt werden.

Zusammengesetzte Eigenschaften animieren

Beim Compositing wird die Seite in Ebenen unterteilt, die Informationen dazu, wie die Seite aussehen soll, in Pixel umgewandelt (Rasterung) und die Ebenen zu einer Seite zusammengesetzt (Compositing).

Aus diesem Grund ist die opacity-Property in der Liste der Elemente enthalten, die sich kostengünstig animieren lassen. Solange sich diese Eigenschaft in einer eigenen Ebene befindet, können Änderungen daran während des Compositing-Schritts von der GPU verarbeitet werden. Chromium-basierte Browser und WebKit erstellen für jedes Element mit einer CSS-Übergang oder -Animation auf opacity eine neue Ebene.

.

Was ist eine Ebene?

Wenn Sie die zu animierenden oder zu übergehenden Elemente auf eine neue Ebene platzieren, muss der Browser nur diese Elemente neu zeichnen und nicht alles andere. Vielleicht kennen Sie das Konzept einer Photoshop-Ebene, die mehrere Elemente enthält, die gemeinsam verschoben werden können. Browser-Rendering-Ebenen funktionieren ähnlich.

Der Browser entscheidet zwar gut, welche Elemente auf einer neuen Ebene sein sollten, aber wenn er eine übersieht, gibt es Möglichkeiten, das Erstellen der Ebene zu erzwingen. Weitere Informationen finden Sie unter Leistungsstarke Animationen erstellen. Das Erstellen neuer Ebenen sollte jedoch mit Bedacht erfolgen, da jede Ebene Arbeitsspeicher belegt. Auf Geräten mit begrenztem Arbeitsspeicher kann das Erstellen neuer Ebenen zu einem größeren Leistungsproblem führen als dem, das Sie beheben möchten. Außerdem müssen die Texturen jeder Ebene auf die GPU hochgeladen werden. Daher kann es zu Bandbreiteneinschränkungen zwischen CPU und GPU kommen.

Leistung von CSS im Vergleich zu JavaScript

Sie fragen sich vielleicht, ob es aus Leistungssicht besser ist, CSS oder JavaScript für Animationen zu verwenden.

CSS-basierte Animationen und Web-Animationen (in Browsern, die die API unterstützen) werden in der Regel in einem Thread verarbeitet, der als Compositor-Thread bezeichnet wird. Dies unterscheidet sich vom Hauptthread des Browsers, in dem Styling, Layout, Painting und JavaScript ausgeführt werden. Das bedeutet, dass diese Animationen auch dann weiterlaufen können, wenn der Browser einige ressourcenintensive Aufgaben im Hauptthread ausführt.

Wie in diesem Artikel erläutert, können auch andere Änderungen an Transformationen und Deckkraft in vielen Fällen vom Compositor-Thread verarbeitet werden.

Wenn eine Animation das Zeichnen, das Layout oder beides auslöst, muss der Hauptthread die Arbeit erledigen. Das gilt sowohl für CSS- als auch für JavaScript-Animationen. Der Overhead von Layout oder Paint wird wahrscheinlich jede Arbeit im Zusammenhang mit der Ausführung von CSS oder JavaScript in den Schatten stellen, sodass die Frage irrelevant wird.