CSS-Zeichenzeiten und -Rendering-Gewichtung

Colt McAnlis
Colt McAnlis

Einführung

Wenn Sie sich für Themen wie die Funktionsweise von Browsern interessieren, haben Sie wahrscheinlich schon einige der hervorragenden Artikel gelesen, die in letzter Zeit über die GPU-beschleunigten Renderer-/Composite-Vorgänge von Chrome veröffentlicht wurden. Zuerst bietet Accelerated Rendering in Chrome: The Layer Model eine gute Einführung dazu, wie Chrome das Konzept von Ebenen zum Zeichnen der Seite verwendet. Für einen tieferen Einblick wird in GPU Accelerated Compositing in Chrome erläutert, wie Chrome diese Ebenen zusammen mit der GPU zum Rendern der Seite verwendet.

Die philosophische Frage

Nachdem ich viel Zeit damit verbracht hatte, Software-Rasterizer für 3D-Zwecke zu schreiben, wurde mir klar, dass einige CSS-Eigenschaften beim Zeichnen Ihrer Seite eine unterschiedliche Leistung haben sollten. Beispielsweise ist das Rastern eines kleinen Bildes auf dem Bildschirm ein völlig anderer algorithmischer Vorgang als das Zeichnen eines Schlagschattens auf einer beliebigen Form. Die Frage war also: Wie wirken sich verschiedene CSS-Eigenschaften auf die Rendering-Gewichtung Ihrer Seite aus?

Mein Ziel war es, eine große Anzahl von CSS-Eigenschaften/-Werten nach ihren Paint-Zeiten zu kategorisieren, um ein Verständnis dafür zu entwickeln, welche Arten von CSS-Eigenschaften leistungsfähiger sind als andere. Dazu habe ich eine Automatisierung mit Klebeband und Kaugummi geschrieben, um die CSS-Paint-Zeiten numerisch sichtbar zu machen. Das hat so funktioniert:

  • Generieren Sie eine Reihe einzelner HTML-Seiten, die jeweils ein einzelnes DOM-Element und eine Permutation von CSS-Eigenschaften enthalten.
  • Führen Sie ein Automatisierungsskript aus, das für jede Seite Folgendes tut:
    • Starten Sie Chrome.
    • Seite laden
    • Erstellen Sie ein Skia-Bild für die Seite.
    • Führe jedes Skia-Bild über Skia Benchmark aus, um die Zeiten zu erhalten.
  • Lassen Sie sich alle Zeitangaben ausgeben und staunen Sie über die Zahlen. (Dieser Teil ist wichtig…)

Mit dieser Einrichtung generieren wir eine Reihe von HTML-Seiten, wobei jede Seite eine eindeutige Permutation von CSS-Eigenschaften und -Werten enthält. Hier sind zwei HTML-Dateien:

<style>
#example1 {
    background: url(foo.png) top left / 50% 60%;
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

Und ein weiteres, komplexeres Beispiel

<style>
#example1 {
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(circle closest-corner, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

Unten sehen Sie eine Variante des letzten Beispiels, bei der nur der Wert für „radial-gradient“ geändert wird:

<style>
#example1 
{
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(farthest-side, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>

Jede Seite wird dann in einer neuen Instanz von Chrome geladen, um sicherzustellen, dass die Zeiten nicht durch veraltete Zustände beim Neuladen der Seite beeinflusst werden. Außerdem wird ein Skia Picture (*.SKP) erstellt, um zu bewerten, welche Skia-Befehle zum Rendern der Seite verwendet werden. Nachdem für jede HTML-Datei SKP-Dateien generiert wurden, führen wir einen weiteren Batch aus, um die *.SKP-Dateien durch die Skia Benchmark-Anwendung (aus dem Skia-Quellcode erstellt) zu leiten. Diese gibt die durchschnittliche Zeit aus, die zum Rendern dieser Seite benötigt wird.

Daten auswerten

Damit können wir jetzt grob darstellen, wie lange das Rendern einer Reihe von CSS-Eigenschaften dauert. Oder besser gesagt, wir können CSS-Eigenschaften nach ihrer Renderingleistung sortieren. Hier ist ein großes Diagramm, das mit der Chrome 27 Beta erstellt wurde und alle Zeitdaten aus diesem Prozess zeigt. Beachten Sie, dass sich alle Daten ändern können, da Chrome mit der Zeit immer schneller wird.

Zeitangaben für alle Permutationen im Test

Jeder vertikale Balken stellt die Paint-Zeit einer Seite mit einer einzelnen Kombination von CSS-Eigenschaften dar (100-fach vergrößert; der tatsächliche Wert dieses Diagramms beträgt 0,1,56 ms). Viele schöne Linien, aber in dieser Form ist das Diagramm ziemlich nutzlos. Wir müssen etwas Data Mining betreiben, um nützliche Trends zu finden.

Zuerst finden wir Belege dafür, dass einige CSS-Eigenschaften einfach teurer zu rendern sind als andere. Das Zeichnen eines Schlagschattens auf ein DOM-Element umfasst beispielsweise einen mehrstufigen Vorgang mit Splines und anderen komplexen Elementen, im Gegensatz zur Deckkraft, die einfacher zu rendern sein sollte.

Zeit, die zum Rendern eines Elements mit nur einer CSS-Eigenschaft benötigt wird

Zweitens, und das ist noch interessanter, können Kombinationen von CSS-Eigenschaften eine längere Paint-Zeit haben als die Summe ihrer Teile. Aus Sicht eines Beobachters ist das etwas seltsam.Wir würden erwarten, dass A + B = C und nicht 2,2 C ist. Beispiel: box-shadow und border-radius-stroke hinzufügen:

Zeitangaben für alle Permutationen im Test

Das Interessante daran ist, dass es nicht nur um die Property box-shadow selbst geht, sondern um diese spezifische Wertpermutation. Unten sehen Sie beispielsweise eine Gruppierung von box-shadow : 50% und border-radius mit Wertvariationen.

Zeitangaben für alle Permutationen im Test

Wenn wir uns die Daten ansehen, geht das eine Weile so weiter. Es gibt viele verschiedene ungewöhnliche Kombinationen, und meine Test-Suite deckt kaum alle ab. Es gibt noch unzählige Tests und Kombinationen, die interessante Ergebnisse liefern könnten.

Rendergewicht der Seite ermitteln

Mit der Möglichkeit, die Renderingzeiten für jedes Element auf Ihrer Seite zu erfassen, können Entwickler die Renderinglast ihrer Seite und deren Auswirkungen auf die Reaktionsfähigkeit Ihrer Website bewerten. Hier sind ein paar Tipps für den Einstieg:

  1. Verwenden Sie den Modus „Kontinuierliches Zeichnen“ in den Chrome-Entwicklertools, um zu sehen, welche CSS-Eigenschaften Sie am meisten kosten.
  2. Integrieren Sie CSS-Reviews in Ihren bestehenden Code-Review-Prozess, um Leistungsprobleme zu erkennen. Suchen Sie in Ihrem CSS nach Stellen, an denen Sie Dinge verwenden, die bekanntermaßen mehr Ressourcen erfordern, wie Farbverläufe und Schatten. Fragen Sie sich: Brauche ich diese hier wirklich?
  3. Im Zweifelsfall sollten Sie sich immer für die bessere Leistung entscheiden. Ihre Nutzenden erinnern sich vielleicht nicht daran, wie breit die Abstände zwischen den Spalten sind, aber sie werden sich daran erinnern, wie es sich anfühlt, Ihre Website zu besuchen.

Schlussgedanken

Einer der interessantesten Aspekte dieses Experiments ist, dass sich die Zeiten mit jeder Chrome-Version weiter ändern werden (hoffentlich werden sie schneller – Browser-Software ist ein sich ständig verändernder Bereich). Was heute langsam ist, kann morgen schnell sein. Sie können aus diesem Artikel mitnehmen, dass Sie box-shadow: 1px 2px 3px 4px nicht auf ein Element anwenden sollten, das bereits border-radius:5 hat. Die wichtigere Erkenntnis ist jedoch, dass CSS-Eigenschaften sich direkt auf die Paint-Zeiten Ihrer Seite auswirken.

Verweise