Umfang und Komplexität von Stilberechnungen reduzieren

JavaScript löst oft visuelle Änderungen aus. Manchmal werden diese Änderungen direkt durch Stiländerungen vorgenommen, manchmal aber auch durch Berechnungen, die zu visuellen Änderungen führen, z. B. durch Suchen oder Sortieren von Daten. JavaScript mit schlechter oder langer Ausführungszeit kann eine häufige Ursache von Leistungsproblemen sein. Daher sollten Sie die Auswirkungen so weit wie möglich minimieren.

Stilberechnung

Wenn Sie das DOM ändern, indem Sie Elemente hinzufügen und entfernen, Attribute, Klassen ändern oder Animationen abspielen, berechnet der Browser die Elementstile und oft auch das Layout eines Teils oder der gesamten Seite neu. Dieser Vorgang wird als berechnete Stilberechnung bezeichnet.

Der Browser beginnt mit der Berechnung von Stilen, indem eine Reihe übereinstimmender Selektoren erstellt wird, um zu bestimmen, welche Klassen, Pseudoselektoren und IDs für ein bestimmtes Element gelten. Anschließend werden die Stilregeln der übereinstimmenden Selektoren verarbeitet und die endgültigen Stile des Elements ermittelt.

Neuberechnungszeit und Interaktionslatenz von Stilen

Interaction to Next Paint (INP) ist ein nutzerorientierter Messwert für die Laufzeitleistung, mit dem die allgemeine Reaktionsfähigkeit einer Seite auf Nutzereingaben bewertet wird. Sie misst die Interaktionslatenz von der Interaktion des Nutzers mit der Seite bis zum Überzeichnen des nächsten Frames durch den Browser mit den entsprechenden visuellen Aktualisierungen der Benutzeroberfläche.

Ein wesentlicher Bestandteil einer Interaktion ist die Zeit, die für das Darstellen des nächsten Frames benötigt wird. Das Rendering der Darstellung des nächsten Frames besteht aus vielen Teilen, einschließlich der Berechnung von Seitenstilen, die kurz vor Layout-, Paint- und Compositing-Arbeiten vorkommen. Auf dieser Seite geht es um die Kosten für die Stilberechnung. Durch das Reduzieren eines beliebigen Teils der Rendering-Phase in Bezug auf die Interaktion wird jedoch auch die Gesamtlatenz reduziert, auch für Stilberechnungen.

Auswahl vereinfachen

Wenn Sie die Selektornamen vereinfachen, können Stilberechnungen für Ihre Seite beschleunigt werden. Die einfachsten Selektoren verweisen auf ein Element in CSS nur mit einem Klassennamen:

.title {
  /* styles */
}

Mit zunehmendem Projektumfang benötigen Sie jedoch wahrscheinlich komplexere CSS-Elemente, sodass Selektoren am Ende so aussehen:

.box:nth-last-child(-n+1) .title {
  /* styles */
}

Um zu bestimmen, wie diese Stile auf die Seite angewendet werden, muss der Browser quasi die Frage stellen: „Ist dies ein Element mit der Klasse title, dessen übergeordnetes Element das untergeordnete Element „minus-nth-plus-1“ mit der Klasse box ist?“ Die Ermittlung der Ergebnisse kann je nach verwendetem Selektor und dem betreffenden Browser sehr lange dauern. Um dies zu vereinfachen, können Sie den Selektor in einen Klassennamen ändern:

.final-box-title {
  /* styles */
}

Diese Ersatzklassennamen mögen ungewohnt erscheinen, aber sie erleichtern dem Browser die Arbeit erheblich. In der vorherigen Version muss der Browser beispielsweise alles über alle anderen Elemente wissen, damit er weiß, dass ein Element das letzte seines Typs ist, um festzustellen, ob nachfolgende Elemente das nth-last-child sein könnten. Dies kann wesentlich rechenintensiver sein als das Abgleichen eines Selektors mit einem Element, nur weil seine Klasse übereinstimmt.

Reduzieren Sie die Anzahl der Elemente, für die ein Stil festgelegt wird

Ein weiterer Leistungsaspekt, der oft wichtiger ist als die Selektorkomplexität, ist der Arbeitsaufwand, der ausgeführt werden muss, wenn sich ein Element ändert.

Im Allgemeinen entsprechen die Kosten für die Berechnung des berechneten Elementstils im schlimmsten Fall der Anzahl der Elemente multipliziert mit der Anzahl der Selektoren. Dies liegt daran, dass der Browser jedes Element mindestens einmal mit jedem Stil vergleichen muss, um zu sehen, ob es übereinstimmt.

Stilberechnungen können direkt auf einige Elemente ausgerichtet sein, anstatt die gesamte Seite zu entwerten. Bei modernen Browsern ist dies in der Regel weniger problematisch, da der Browser nicht immer alle Elemente überprüfen muss, auf die sich eine Änderung auswirken könnte. Ältere Browser sind hingegen nicht immer für solche Aufgaben optimiert. Wenn möglich, sollten Sie die Anzahl der ungültigen Elemente reduzieren.

Kosten für die Stilneuberechnung messen

Eine Möglichkeit, die Kosten für Stilneuberechnungen zu messen, ist der Leistungsbereich in den Chrome-Entwicklertools. Gehen Sie dazu so vor:

  1. Öffnen Sie die Entwicklertools.
  2. Rufen Sie den Tab Leistung auf.
  3. Klicken Sie auf Aufzeichnen.
  4. Interagieren Sie mit der Seite.

Wenn Sie die Aufzeichnung beenden, sehen Sie in etwa folgende Abbildung:

Entwicklertools, die Stilberechnungen zeigen
Ein Entwicklertools-Bericht mit Stilberechnungen.

Der Streifen oben ist ein Mini-Flamendiagramm, das auch Frames pro Sekunde darstellt. Je näher sich die Aktivität am unteren Rand des Streifens befindet, desto schneller werden die Frames vom Browser dargestellt. Wenn sich das Flame-Diagramm oben mit roten Balken oben ausgleicht, haben Sie Arbeit, die lang andauernde Frames verursacht.

Heranzoomen eines Problembereichs in den Chrome-Entwicklertools in der Aktivitätsübersicht des ausgefüllten Leistungsbereichs in den Chrome-Entwicklertools.
Frames mit langer Ausführungszeit in der Aktivitätszusammenfassung der Entwicklertools.

Dauerhafte Frames bei einer Interaktion wie Scrollen sollten genauer betrachtet werden. Wenn Sie einen großen lila Block sehen, zoomen Sie die Aktivität heran und wählen Sie ein beliebiges Werk mit dem Label Stil neu berechnen aus, um weitere Informationen über möglicherweise teure Stilneuberechnungen zu erhalten.

Abrufen der Details lang andauernder Stilberechnungen, einschließlich wichtiger Informationen wie der Anzahl der Elemente, die von der Stilneuberechnung betroffen sind
Eine lang andauernde Stilneuberechnung dauert in der Entwicklertools-Zusammenfassung etwas mehr als 25 ms.

Wenn Sie auf das Ereignis klicken, wird der zugehörige Aufrufstack angezeigt. Wenn das Rendering durch eine Nutzerinteraktion verursacht wurde, wird das JavaScript aufgerufen, das die Stiländerung ausgelöst hat. Außerdem wird die Anzahl der Elemente angezeigt, auf die sich die Änderung auswirkt – in diesem Fall etwas mehr als 900 Elemente – und wie lange die Stilberechnung gedauert hat. Anhand dieser Informationen können Sie versuchen, eine Fehlerbehebung in Ihrem Code zu finden.

Block, Element, Modifikator verwenden

Bei Programmierungsstrategien wie BEM (Block, Element, Modifier) werden die Leistungsvorteile des Selektor-Abgleichs berücksichtigt. BEM empfiehlt, dass alles eine einzelne Klasse hat. Wenn eine Hierarchie erforderlich ist, wird diese Hierarchie auch in den Klassennamen verankert:

.list {
  /* Styles */
}

.list__list-item {
  /* Styles */
}

Wenn Sie einen Modifizierer wie im Beispiel mit dem letzten untergeordneten Element benötigen, können Sie diesen wie folgt hinzufügen:

.list__list-item--last-child {
  /* Styles */
}

BEM ist ein guter Ausgangspunkt für die Strukturierung Ihres CSS, sowohl aus struktureller Sicht als auch aufgrund der vereinfachten Stilsuche.

Wenn Ihnen BEM nicht gefällt, gibt es andere Möglichkeiten, Ihr Preisvergleichsportal anzugehen. Sie sollten jedoch zuerst die Leistung und Ergonomie prüfen.

Ressourcen

Hero-Image aus Unsplash von Markus Spiske