Référence rapide

Aide-mémoire Layout Thrashing et Reflow forcé

Guide complet sur le layout thrashing et le forced reflow : propriétés d’éléments DOM, événements souris, méthodes window et déclencheurs jQuery dégradant le rendu.

· Publié le

Le layout thrashing (ou mise en page synchrone forcée / reflow forcé) survient lorsque JavaScript alterne sans cesse entre l’écriture dans le DOM et la lecture de propriétés de géométrie, obligeant le navigateur à recalculer la mise en page de façon synchrone.

Déclencheurs d’invalidation du layout

Les propriétés et méthodes DOM suivantes forcent le recalcul synchrone de la géométrie dès que la mise en page a été invalidée par des mutations DOM antérieures.

Propriétés et méthodes des éléments

Géométrie et dimensions de boîte

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

Requête de boîtes englobantes

  • getBoundingClientRect()
  • getClientRects()

Actions de défilement

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

Texte et focus

  • innerText
  • outerText
  • focus() (force l’anneau de focus et les ajustements de défilement)

Propriétés d’événement souris

Interroger certaines coordonnées sur un objet MouseEvent peut déclencher un calcul de mise en page selon le moteur :

  • layerX, layerY
  • offsetX, offsetY

Méthodes et propriétés Window

  • window.getComputedStyle() (lors de la lecture de valeurs dépendant de la mise en page telles que largeur, hauteur ou marges)
  • window.scrollBy()
  • window.scrollTo()
  • window.scrollX, window.scrollY

Frame, document et image

  • Lecture de width ou height sur une image avant stabilisation du layout
  • Accès à document.body.scrollHeight

Opérations jQuery

De nombreuses méthodes utilitaires jQuery lisent en interne les dimensions calculées :

// Déclenche un reflow
$(elem).offset();
$(elem).offsetParent();
$(elem).position();
$(elem).scrollLeft();
$(elem).scrollTop();
$(elem).css('width');  // Tout calcul de style dépendant de la mise en page
$(elem).text();

// Pseudo-sélecteurs inspectant la visibilité géométrique
$(':hidden');
$(':visible');
$(':contains');

Bonnes pratiques contre le Layout Thrashing

1. Regrouper lectures et écritures par lots

Effectuez toujours toutes les mesures DOM d’abord, puis regroupez toutes les modifications DOM ensemble.

// À ÉVITER : Entrelacer lecture et écriture force un recalcul à chaque itération
elements.forEach((el) => {
  const width = el.clientWidth; // LECTURE (force le layout)
  el.style.width = width * 2 + 'px'; // ÉCRITURE (invalide le layout)
});

// RECOMMANDÉ : Lectures groupées, puis écritures groupées
const widths = elements.map((el) => el.clientWidth); // LECTURE GROUPÉE
elements.forEach((el, index) => {
  el.style.width = widths[index] * 2 + 'px'; // ÉCRITURE GROUPÉE
});

2. Utiliser requestAnimationFrame

Planifiez les écritures de style dans la prochaine image d’animation afin d’optimiser le cycle de rendu :

const height = element.clientHeight; // Lecture durant la phase courante

window.requestAnimationFrame(() => {
  element.style.height = height + 50 + 'px'; // Écriture dans l’image suivante
});

3. Utiliser CSS Transforms et Opacity

Privilégiez l’animation des propriétés CSS gérées sur le fil de composition (transform, opacity) plutôt que des propriétés de mise en page (top, left, width, height).


Références

Sujets associés