Document ID: /fineweb-2-swissfilter-quality_10-filterrobots/filtered/03559.jsonl.gz/86

4/4/2019
Was ist Layout Thrashing?
Layout Thrashing bedeutet, dass der Browser die Positionen und Grössen der DOM-Elemente mehrmals neu berechnen muss, bevor die Seite schlussendlich "geladen" und dem Benutzer angezeigt werden kann. Im optimalen Fall wird die Kalkulation vom Layout nur einmal durchgeführt. Der Ablauf, welcher das Bild zum Benutzer bringt, sieht dann wie folgt aus:
Nehmen wir nun jedoch dieses Beispiel:
Es werden von drei Elementen nacheinander die height verdoppelt. Um die height vom ersten Element zu verdoppeln, wird clientHeight ausgelesen. So weit so gut. Nun wird die height vom element1 gesetzt, indem die zuvor ausgelesene clientHeight verdoppelt wird. Diese Aktion führt dazu, dass das Layout "invalid" wird, da sich ein Element darin verändert hat. Der Browser reagiert jedoch noch nicht, wenn das Layout lediglich invalid ist. Das wird sich aber schnell ändern, denn: Um vom element2 die clientHeight herauslesen zu können, muss das Layout nun neu kalkuliert werden, da es vorher invalidiert wurde - Layout Thrashing passiert. Das selbe Prozedere für das element3. Es wird aus dem JavaScript gezwungen, das Layout neu zu kalkulieren. Der Browser springt vom JavaScript zum Layout und wieder zurück, so viele Male, wie es nötigt ist:
Es gibt viele Fälle, welche Layout Thrashing auslösen. Eine Liste mit allen Umständen finden Sie hier: gist.github.com/paulirish/5d52fb081b3570c81e3a
Layout Thrashing vermindern
Eine einfache Lösung um Layout Thrashing zu vermeiden ist, alle benötigten Werte zuerst auszulesen, und dann erst die Elemente zu ändern:
Zugegebenermassen funktioniert dies in der realen Welt wohl nur in den aller seltensten Fällen so einfach. Aber keine Angst, es gibt auch für komplexere Use-Cases eine Lösung: window.requestAnimationFrame(). Diese terminiert eine Funktion zum ausführen im nächsten Frame, ähnlich setTimeout().
Um zu sehen, wie gross die Performanceverbesserung in einem solchen Fall ist, habe ich eine simple Applikation in StackBlitz erstellt. Diese erstellt zu Anfang 1000 div-Elemente. Die zwei Buttons oben machen grundsätzlich das Selbe - sie iterieren über die Elemente und verdoppeln ihre height. Einziger Unterschied ist, der eine macht es unperfomant, also mit Layout Thrashing, der Andere macht sich der requestAnimationFrame() Funktion zu nutze:
Ergebnis
Mit Layout Thrashing (links) benötigen 1000 Elemente 457.2 ms fürs Rendering, rechts, mit Hilfe von requestAnimationFrame() gerade mal noch 12.1 ms! Überzeugt?
Versuchen Sie selber im Editor und den Performance-Dev-Tools Ihres Browsers herumzuspielen, um die Sache genauer anschauen zu können!
Für Fragen und Anregungen stehe ich gerne zur Verfügung.