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:
- 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ě.
- Používat
transformaopacity: 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. - 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. - Virtuální seznamy: Vykreslovat pouze prvky seznamu, které jsou aktuálně viditelné, čímž se výrazně sníží počet prvků v DOM.
- 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: absoluteneboposition: fixed), provést animaci a poté jej vrátit zpět. - 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;
}