Snelle referentie

Layout Thrashing & Forced Reflow Spiekbriefje

Uitgebreide referentiegids voor layout thrashing en forced reflow: DOM-elementeigenschappen, muisgebeurtenissen, window-methoden en jQuery-triggers die rendering vertragen.

· Gepubliceerd

Layout thrashing (ook bekend als geforceerde synchrone lay-out of forced reflow) treedt op wanneer JavaScript herhaaldelijk wisselt tussen schrijven naar de DOM en lezen van lay-outeigenschappen, waardoor de browser gedwongen wordt de lay-out synchroon opnieuw te berekenen.

Triggers voor Lay-outinvalidatie

De volgende DOM-eigenschappen en -methoden dwingen een synchrone herberekening van de geometrie af zodra de lay-out ongeldig is gemaakt door eerdere DOM-wijzigingen.

Elementeigenschappen & Methoden

Boxgeometrie & Afmetingen

  • clientHeight, clientWidth
  • clientLeft, clientTop
  • offsetHeight, offsetWidth
  • offsetLeft, offsetTop
  • offsetParent
  • scrollHeight, scrollWidth
  • scrollLeft, scrollTop

Bounding Boxes Opvragen

  • getBoundingClientRect()
  • getClientRects()

Scroll-acties

  • scrollIntoView()
  • scrollIntoViewIfNeeded()
  • scrollByLines()
  • scrollByPages()

Tekst & Focus

  • innerText
  • outerText
  • focus() (forceert aanpassingen voor focusring en scrollen)

Muisgebeurteniseigenschappen

Het opvragen van bepaalde coördinaten op een MouseEvent-instantie kan lay-outberekening activeren in sommige browserengines:

  • layerX, layerY
  • offsetX, offsetY

Window-methoden & Eigenschappen

  • window.getComputedStyle() (bij het opvragen van lay-outafhankelijke waarden zoals breedte, hoogte, marge of transform)
  • window.scrollBy()
  • window.scrollTo()
  • window.scrollX, window.scrollY

Frame, Document & Afbeelding

  • width of height op een afbeelding opvragen voordat de lay-out stabiel is
  • Toegang tot document.body.scrollHeight

jQuery-operaties

Veel jQuery-hulpmethoden lezen onder water berekende lay-outwaarden uit:

// Activeert reflow
$(elem).offset();
$(elem).offsetParent();
$(elem).position();
$(elem).scrollLeft();
$(elem).scrollTop();
$(elem).css('width');  // Elke lay-outafhankelijke stijlberekening
$(elem).text();

// Pseudoselectoren die geometrische zichtbaarheid inspecteren
$(':hidden');
$(':visible');
$(':contains');

Aanbevolen Praktijken tegen Layout Thrashing

1. Lees- en Schrijfopdrachten Bundelen

Voer altijd eerst alle DOM-metingen uit en voer vervolgens alle DOM-mutaties gezamenlijk uit.

// FOUT: Afwisselend lezen en schrijven veroorzaakt bij elke stap een gedwongen lay-out
elements.forEach((el) => {
  const width = el.clientWidth; // LEZEN (forceert lay-out)
  el.style.width = width * 2 + 'px'; // SCHRIJVEN (invalideert lay-out)
});

// GOED: Eerst gebundeld lezen, daarna gebundeld schrijven
const widths = elements.map((el) => el.clientWidth); // GEBUNDELD LEZEN
elements.forEach((el, index) => {
  el.style.width = widths[index] * 2 + 'px'; // GEBUNDELD SCHRIJVEN
});

2. Gebruik requestAnimationFrame

Plan stijlaanpassingen in het volgende animatieframe zodat de browser de rendercyclus kan optimaliseren:

const height = element.clientHeight; // Lezen tijdens huidige fase

window.requestAnimationFrame(() => {
  element.style.height = height + 50 + 'px'; // Schrijven in het volgende frame
});

3. Gebruik CSS Transforms & Opacity

Geef voor animaties de voorkeur aan CSS-eigenschappen op de compositor-thread (transform, opacity) in plaats van lay-outeigenschappen (top, left, width, height).


Referenties

Verwante onderwerpen