Moderne Browser können zwei CSS-Properties kostengünstig animieren: transform und opacity.
Wenn Sie etwas anderes animieren, ist es wahrscheinlich, dass Sie keine flüssigen 60 fps (Bilder pro Sekunde) erreichen.
In diesem Beitrag wird erläutert, warum das so ist.
Animationsleistung und Framerate
Eine Framerate von 60 fps gilt allgemein als Ziel für die Animation von Inhalten im Web. Diese Bildrate sorgt dafür, dass Ihre Animationen flüssig aussehen. Im Web ist ein Frame die Zeit, die benötigt wird, um alle erforderlichen Aufgaben zum Aktualisieren und Neuzeichnen des Bildschirms auszuführen. Wenn jeder Frame nicht innerhalb von 16,7 ms (1.000 ms / 60 ≈ 16,7) gerendert wird, nehmen Nutzer die Verzögerung wahr.
Die Rendering-Pipeline
Damit etwas auf einer Webseite angezeigt werden kann, muss der Browser die folgenden sequenziellen Schritte ausführen:
- Stil: Berechnet die Stile, die auf die Elemente angewendet werden.
- Layout: Generiert die Geometrie und Position für jedes Element.
- Malen: Füllen Sie die Pixel für jedes Element aus.
- Zusammensetzen: Die Elemente werden in Ebenen aufgeteilt und auf dem Bildschirm dargestellt.
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 wiederholt werden. Dieser Prozess beginnt mit dem Schritt, der geändert werden muss, damit die Animation ausgeführt werden kann.
Wie bereits erwähnt, sind diese Schritte sequenziell. Wenn Sie beispielsweise etwas animieren, das das Layout ändert, müssen auch die Schritte „Rendern“ und „Zusammenfügen“ noch einmal ausgeführt werden. Das Animieren von Elementen, die das Layout ändern, ist daher aufwendiger als das Animieren von Elementen, die nur das Compositing ändern.
Layoutattribute animieren
Bei Layoutänderungen wird die Geometrie (Position und Größe) aller von der Änderung betroffenen Elemente berechnet.
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 alle untergeordneten Elemente auswirken.
Da Elemente überlaufen und sich gegenseitig beeinflussen, können Änderungen weiter unten im Baum manchmal zu Layoutberechnungen bis ganz nach oben führen.
Je größer der Baum sichtbarer Elemente, desto länger dauert es, Layoutberechnungen durchzuführen.
Malattribute animieren
Rendern ist der Prozess, bei dem bestimmt wird, in welcher Reihenfolge Elemente auf dem Bildschirm gerendert werden sollen. Sie ist oft die Aufgabe in der Pipeline, die am längsten dauert.
Die meisten Rendering-Vorgänge in modernen Browsern werden von Software-Rasterizern ausgeführt. Je nachdem, wie die Elemente in Ihrer App in Ebenen gruppiert sind, müssen möglicherweise auch andere Elemente als das geänderte neu gezeichnet werden.
Zusammengesetzte Eigenschaften animieren
Beim Compositing wird die Seite in Ebenen unterteilt, die Informationen darüber, wie die Seite aussehen soll, werden in Pixel umgewandelt (Rasterung) und die Ebenen werden zusammengefügt, um eine Seite zu erstellen (Compositing).
Aus diesem Grund ist die Property opacity in der Liste der Dinge enthalten, die sich kostengünstig animieren lassen.
Solange sich diese Property 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 eine neue Ebene für jedes Element, das einen CSS-Übergang oder eine CSS-Animation auf opacity hat.
Was ist eine Ebene?
Wenn Sie die Elemente, die animiert oder in die übergegangen werden sollen, auf eine neue Ebene legen, muss der Browser nur diese Elemente neu rendern und nicht alles andere. Vielleicht kennen Sie das Konzept einer Ebene aus Photoshop, die eine Reihe von Elementen enthält, die zusammen verschoben werden können. Browser-Rendering-Ebenen funktionieren ähnlich.
Der Browser trifft zwar in der Regel gute Entscheidungen darüber, welche Elemente auf einer neuen Ebene platziert werden sollen, aber wenn er ein Element übersieht, gibt es Möglichkeiten, die Erstellung einer Ebene zu erzwingen. Weitere Informationen dazu 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 Speicherplatz kann das Erstellen neuer Ebenen zu größeren Leistungsproblemen führen als das, was Sie eigentlich beheben möchten. Außerdem müssen die Texturen jeder Ebene auf die GPU hochgeladen werden. Daher kann es durchaus zu Einschränkungen der Bandbreite zwischen CPU und GPU kommen.
Leistung von CSS im Vergleich zu JavaScript
Vielleicht fragen Sie sich, ob es aus Leistungssicht besser ist, CSS oder JavaScript für Animationen zu verwenden.
CSS-basierte Animationen und Web Animations (in den 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, Rendering und JavaScript ausgeführt werden. Wenn der Browser also einige rechenintensive Aufgaben im Hauptthread ausführt, können diese Animationen ohne Unterbrechung fortgesetzt werden.
Wie in diesem Artikel beschrieben, können andere Änderungen an Transformationen und der Deckkraft in vielen Fällen auch vom Compositor-Thread verarbeitet werden.
Wenn eine Animation das Rendern, 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 Aufwand für Layout oder Rendering wird wahrscheinlich jede Arbeit im Zusammenhang mit der CSS- oder JavaScript-Ausführung in den Schatten stellen, sodass die Frage hinfällig wird.