almessadi.
Zur Übersicht

Layout-Thrashing beginnt, wenn DOM-Lese- und Schreiboperationen gegeneinander kämpfen_

Geometrie-APIs wie `getBoundingClientRect()` sind nützlich, aber sie werden kostspielig, wenn der Code wiederholt frisches Layout mitten in Stil- und DOM-Aktualisierungen erzwingt.

Veröffentlicht10. Dezember 2024
Lesezeit6 min read

Der Browser möchte die Stilberechnung und die Layout-Arbeiten bündeln. Leistungsprobleme treten auf, wenn Anwendungs-Code diesen Plan ständig unterbricht, indem er abwechselnd DOM-Schreiboperationen und Layout-Leseoperationen in engen Schleifen ausführt.

Dieses Muster wird normalerweise als Layout-Thrashing bezeichnet.

Das Fehler-Muster

Das ist die kostspielige Form:

for (const item of items) {
  item.style.width = "200px";
  const rect = item.getBoundingClientRect();
  item.style.height = `${rect.width}px`;
}

Jeder Aufruf von getBoundingClientRect() kann den Browser zwingen, ausstehende Layout-Arbeiten abzuschließen, bevor er antworten kann. Wenn dies während des Scrollens, Resizings oder einer Animation geschieht, wird die Benutzeroberfläche schnell ruckelig.

Besseres Muster

Zuerst die Leseoperationen bündeln. Zweitens die Schreiboperationen bündeln:

const widths = items.map((item) => item.getBoundingClientRect().width);

items.forEach((item, index) => {
  item.style.width = "200px";
  item.style.height = `${widths[index]}px`;
});

Das ist nicht der einzige mögliche Fix, aber es zeigt die zugrunde liegende Regel: Vermeide es, den Browser wiederholt zur Neuberechnung des Layouts innerhalb von rahmensensitiven Code zu zwingen.

Wann es tatsächlich wichtig ist

Man merkt es normalerweise in:

  • Scroll-Handlern
  • Animationsschleifen
  • Drag-and-Drop-Interaktionen
  • großen Listen mit direkter DOM-Manipulation

Der Browser ist schnell, wenn du ihm die Arbeit bündeln lässt. Es wird kostspielig, wenn du ihn zwingst, geometrische Fragen sofort nach jedem Schreibvorgang zu beantworten.

Wenn der Code während einer Animation oder Interaktion ausgeführt werden muss, ist requestAnimationFrame oft der richtige Ort, um gebündelte DOM-Arbeiten zu planen, sodass Lese- und Schreiboperationen in einem vorhersehbareren Rahmen durchgeführt werden.

Weitere Informationen