Riferimento rapido

Cheatsheet Layout Thrashing e Forced Reflow

Guida completa a layout thrashing e forced reflow: proprietà DOM, eventi del mouse, metodi window e trigger jQuery che degradano le prestazioni di rendering.

· Pubblicato

Il layout thrashing (noto anche come layout sincrono forzato o forced reflow) si verifica quando JavaScript alterna ripetutamente scritture nel DOM e letture delle proprietà di layout, costringendo il browser a ricalcolare il layout in modo sincrono.

Trigger di Invalidazione del Layout

Le seguenti proprietà e metodi DOM forzano il ricalcolo sincrono della geometria ogni volta che il layout è stato invalidato da precedenti mutazioni.

Proprietà e Metodi degli Elementi

Geometria e Dimensioni Box

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

Interrogazione Bounding Box

  • getBoundingClientRect()
  • getClientRects()

Azioni di Scorrimento

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

Testo e Focus

  • innerText
  • outerText
  • focus() (forza anello di focus e aggiustamenti dello scorrimento)

Proprietà di MouseEvent

Interrogare determinate coordinate su un’istanza MouseEvent può innescare il calcolo del layout in alcuni motori di rendering:

  • layerX, layerY
  • offsetX, offsetY

Metodi e Proprietà di Window

  • window.getComputedStyle() (quando si interrogano valori dipendenti dal layout come width, height o margin)
  • window.scrollBy()
  • window.scrollTo()
  • window.scrollX, window.scrollY

Frame, Documento e Immagine

  • Interrogazione di width o height su un’immagine prima della stabilizzazione del layout
  • Accesso a document.body.scrollHeight

Operazioni jQuery

Molti metodi helper di jQuery leggono internamente valori calcolati di layout:

// Innesca reflow
$(elem).offset();
$(elem).offsetParent();
$(elem).position();
$(elem).scrollLeft();
$(elem).scrollTop();
$(elem).css('width');  // Qualsiasi calcolo di stile dipendente dal layout
$(elem).text();

// Pseudo-selettori che verificano la visibilità geometrica
$(':hidden');
$(':visible');
$(':contains');

Best Practice per Evitare il Layout Thrashing

1. Raggruppa Letture e Scritture

Esegui sempre prima tutte le misurazioni DOM, poi raggruppa tutte le modifiche insieme.

// MALE: Alternare letture e scritture forza il layout ad ogni iterazione
elements.forEach((el) => {
  const width = el.clientWidth; // LETTURA (forza layout)
  el.style.width = width * 2 + 'px'; // SCRITTURA (invalida layout)
});

// BENE: Prima letture in batch, poi scritture in batch
const widths = elements.map((el) => el.clientWidth); // LETTURA IN BATCH
elements.forEach((el, index) => {
  el.style.width = widths[index] * 2 + 'px'; // SCRITTURA IN BATCH
});

2. Usa requestAnimationFrame

Pianifica le modifiche di stile nel frame di animazione successivo per ottimizzare il ciclo di rendering:

const height = element.clientHeight; // Leggi nella fase corrente

window.requestAnimationFrame(() => {
  element.style.height = height + 50 + 'px'; // Scrivi nel frame successivo
});

3. Usa CSS Transforms e Opacity

Preferisci animare proprietà CSS gestite dal compositor thread (transform, opacity) rispetto a proprietà di layout (top, left, width, height).


Riferimenti

Argomenti correlati