Sobes.tech
Middle

Jaké způsoby optimalizace renderování (reflow) znáš?

sobes.tech AI

Odpověď od AI

Optimalizace vykreslování (přepočet stylů a rozvržení) je dosažena minimalizací nebo odstraněním operací, které vyvolávají Layout (režim nebo přepočet pozic a velikostí prvků). K těmto operacím patří:

  • Změna geometrických vlastností: width, height, left, top, margin, padding.
  • Změna obsahu: přidání/odstranění uzlů, změna textu.
  • Změna vlastností ovlivňujících tok dokumentu: display, float, position.
  • Získání vypočtených stylů nebo rozměrů: element.offsetWidth, getComputedStyle().
  • Změna velikosti okna prohlížeče.

Způsoby optimalizace:

  1. Vyhnout se synchronním nuceným Layoutům: Získávat informace o stylu/rozvržení před provedením změn, které by mohly spustit Layout, a poté provádět všechny změny hromadně.
  2. Používat transform a opacity: Tyto vlastnosti mění prvek, aniž by ovlivnily geometrii ostatních prvků, způsobují pouze Composite (skládání) a Paint (překreslení), ale ne Layout.
  3. Používat will-change: Atribut informuje prohlížeč o předpokládaných změnách prvku, což umožňuje optimalizovat vykreslování předem (například přesunem prvku na samostatnou GPU vrstvu). Je třeba používat rozumně, protože to může zvýšit spotřebu paměti.
  4. Virtuální seznamy: Vykreslovat pouze prvky seznamu, které jsou aktuálně viditelné, čímž se výrazně sníží počet prvků v DOM.
  5. Odstranění prvku z toku: Pro složité animace, které vyžadují časté změny geometrických vlastností, lze dočasně odstranit prvek z normálního toku dokumentu (například pomocí position: absolute nebo position: fixed), provést animaci a poté jej vrátit zpět.
  6. Debouncing a throttling událostí: Omezit frekvenci volání obslužných funkcí událostí (například posouvání nebo změny velikosti okna), které mohou spouštět Layout.
// Příklad synchronního nuceného Layoutu
const element = document.getElementById('myElement');
const height = element.offsetHeight; // Vyvolá Layout
element.style.height = (height + 10) + 'px'; // Vyvolá Layout znovu

// Optimalizovaný příklad (hromadná změna)
const element = document.getElementById('myElement');
// Získáme hodnotu před změnami
const height = element.offsetHeight; 
// Provedeme všechny změny najednou
element.style.height = (height + 10) + 'px'; 
element.style.width = (element.offsetWidth + 10) + 'px';
/* Použití transform místo left/top pro animaci */
.animated-element {
  transform: translateX(100px); /* Vyvolá Composite */
  /* Místo left: 100px; což způsobuje Layout a Paint */
}

/* Použití will-change */
.will-animate {
  will-change: transform, opacity; 
}