Rychlost zpracování změn CSS

CSS styly musejí reagovat na celou řadu změn ve stránce, ať už je to akce uživatele (:hover či :focus) nebo programové změny (class či přidání DOM prvků). A zatímco některé změny jsou pro prohlížeč hračkou (např. změna barvy rámečku), tak nad některými musí strávit dlouhý čas, aby je do stránky přidal (např. změna šířky rámečku z 1px na 2px).

Tři úrovně změny

Při každé změně CSS stylu spadá změna každé vlastnosti do jedné kategorie podle toho, co ve stránce změní: rozvržení, uspořádání a vykreslení. (Přičemž změna rozvržení změní i uspořádání a změna uspořádání (většinou) vynutí překreslení).

A zatímco změny ve vykreslení a uspořádání znamenají pro prohlížeč jen překreslení změněné části stránky, změna v rozvržení pro něj znamená přepočítat celý layout stránky, znovu ho sestavit (reflow) a vykreslit.

Při změně stylu byste tedy vždy měli uvažovat nad tím, jak potřebná je daná změna, co ve stránce ovlivní a na jak dlouho to prohlížeč zaměstná. Jak už jsem psal v úvodu, změnit barvu nebo vzhled existujícího rámečku je mnohem rychlejší, než přidávat nový rámeček nebo měnit jeho šířku.

Zvláště důležité je to u animací, které změnu vyvolávají dlouhodobě a/nebo opakovaně a přepočítávat několikrát celou stránku jen proto, že chcete prvkem (třeba nevalidním inputem) zatřást ze strany na stranu je nesmysl. Pokud animaci nahradíte například probliknutím barvy rámečku a změnou ze solid na dashed, ušetříte spoustu času (a také baterie mobilních zařízení).

Rozvržení stránky (page layout)

Rozvržení stránky, tedy to jak jsou prvky umístěny a jak jsou velké, ovlivňují vlastnosti jako display, width, height, margin, border-width, box-sizing, font-size,  a prostě vše, co může daný prvek po stránce posunout a nebo změnit jeho velikost (za předpokladu, že má position=static).

Pokud například změníte o 1px výšku nadpisu stránka, nemůže prohlížeč jen posunout stránku o 1px (nahoru nebo dolu), ale musí přepočítat celý její obsah – vypočítat znovu rozměry všech prvků, znovu je do stránky umístit a znova vykreslit.

Vlastnosti jako padding(při box-sizing: border-box), overflownebo align-items také mění rozvržení stránky, ale jen uvnitř daného prvku, takže při jejich změně nemusí prohlížeč znova přepočítávat celou stránku ale jen obsah daného kontejneru. Pokud je tím kontejnerem třeba jen obal (wrapper) obrázku, bude změna rychlá (překreslí se obrázek). Pokud ale změníte overflow na BODY, bude muset prohlížeč opět překreslit celou stránku.

I další vlastnosti mohou měnit velikost prvků, například content mění velikost podle zobrazeného textu nebo quotes mění velikost protože změní znaky před a za textem, white-space nebo text-overflow mění, jak je text v prvku zobrazen, atd.

Pokud chcete pro příklad přidat nevalidnímu prvku červený rámeček, který předtím neměl, změníte tím rozložení stránky a prohlížeč ji bude muset přepočítat. Pokud ale ve výchozím stylu nastavíte prvku průhledný okraj a pak jen změníte jeho barvu na červenou, kroky Rozložení a Uspořádání se tím přeskočí:

//Tohle je špatný přístup z několika důvodů
input {
    border: 0 none;
}
input:invalid {
    border: 1px solid red;
}

//Tohle je mnohem lepší
input {
    border: 1px solid transparent;
}
input:invalid {
    border-color: red;
}

Uspořádání stránky (page composition)

Uspořádání stránky znamená rozložení prvků ve třetím rozměru, tedy to, jak jsou prvky poskládány na sebe a který je vidět „na vrchu“. Ve výchozím rozložení se prvky nepřekrývají, ale pokud použijete position s hodnotami static, absolute nebo fixed (a pak měníte související top, left, atd.) nebo třeba nastavíte overflow: visible a text vyteče z prvku, mohou se prvky začít překrývat a prohlížeč tedy musí zjistit, který má vykreslit (ten na vrchu). Další komplikací v uspořádání je průhlednost, ať už vynucená (opacity: 0.5), přirozená (color: rgba(0,0,0,0.5)) nebo výchozí (většina prvků má průhledné pozadí), protože pak musí prohlížeč vykreslit více prvků přes sebe a spočítat prolnutí barev.

Poznámka: Definice background: transparent nastavuje barvu pozadí na průhlednou a odpovídá tedy background-color: rgba(0,0,0,0), zatímco background: none ruší obrázek na pozadí a tudíž odpovídá background-image: none. Nicméně použití background nastaví všechny neuvedené hodnoty na výchozí, takže background: nonemá stejný účinek jako background: transparent.

Ve výchozím stavu jsou prvky HTML skládány na sebe tak, jak jsou uvedeny v HTML kódu, ale změnit to můžete například CSS vlastností z-index. Nepřímo může uspořádání ovlivnit i vlastnosti visibility: hidden, která prvek sice do stránky umístí, ale zabrání jeho vykreslení, takže efektivně bude „na vrchu“ prkvek pod ním.

Další vlastnosti, které mohou nepřímo změnit uspořádání a vést k nutnosti překreslit stránku jsou border-radius (mění viditelnost prvků pod okrajem), box-shadow (mění prolnutí do prvků níže) a filter (mění viditelnost prvku).

V případě, že používáte position: fixed, background-attachment: fixed nebo pespektivu, vyvolává změnu uspořádání i posun stránky (scroll), protože část stránky se posouvá a jiná zůstává na místě (nebo se posouvají jinou rychlostí) a tak není možné prostě jen pošoupnout již vykreslené pixely, ale je potřeba je znova přepočítat.

Důležité je si uvědomit, že změnou z-index neměníte rozměry ani umístění prvků (v osách X a Y) a tudíž je prohlížeč nemusí přepočítávat (vyhne se tedy kroku změna rozvržení).

Pokud například chcete na stránce prohazovat dva prvky (např. tlačítko Refresh a ikonu Loading), zkuste místo display: none a display: block (které mění rozložení stránky) udělat prvky neprůhledné a měnit jen jejich z-index, opacity nebo visibility, aby prohlížeč jen přepočítal jejich uspořádání a překreslil je.

Moderní prohlížeče navíc používají 3D rendering grafických karet, takže sami neurčují, který prvek je „na vrchu“, ale vykreslí všechny do různých vrstev (layers), přidají k nim informaci o jejich pozici v ose Z a grafická karta sama se pak postará o správné vykreslení (ne)průhledných částí. V takovém případě změna z-index jednoho prvku nepředstavuje pro prohlížeč žádnou zátěž, protože není potřeba nic překreslovat a jen se grafické kartě pošle informace o posunu prvku v 3D prostoru.

Vykreslení stránky (page paint)

Posledním typem změny stránky je její vykreslení, tedy fyzický převod HTML atributů a CSS vlastností na viditelné pixely.

I když by se z předchozího textu mohlo zdát, že vykreslení je tím poslední a nejjednodušším krokem, tak opak je pravdou a vykreslení zabírá většinu čas potřebného k aplikaci změn CSS.

Nicméně pořád je rozdíl v tom, zda je potřeba stránku pouze překreslit, nebo je potřeba ještě přepočítat rozměry a umístění všech prvků. Vždy se tedy snažte uvažovat nad tím, co daná změna CSS znamená a jak složité to pro prohlížeč bude.

Kromě výše uvedených změn rozložení a uspořádání vyvolává změnu vykreslení i všechny CSS pravidla měnící barvu (color, background-color, border-color, atd.) nebo jakýmkoliv jiným způsobem mění vnitřní vzhled prvku (outline, text-aligna většina text-* vlastností), background-image a související position, size, atd., vertical-align, overflow: auto/hidden/scroll, apod.).

Změny bez obětí

Samozřejmě existují i CSS vlastnosti, které nic samotný vzhled stránky neovlivní a není tak potřeba stránku překreslovat.

Například vlastnosti cursora caret-color mění vzhled kurzorů myši a klávesnice, které nejsou součástí stránky a tak není potřeba nic překreslovat.

Vlastnost speak mění způsob přístupu asistenčních služeb text-to-speech (např. speak: spell-out) a neovlivňuje tedy grafický vzhled stránky (stejně jako color nezmění způsob, jak TTS text přečte).

Vlastnosti break-before/break-after a orphans/ widows, mění pouze vzhled při tisku a tak nemají vliv na zobrazení stránky v prohlížeči.

Rozsah změn

I výše uvedené typy změn nejsou úplně jednoznačné a prohlížeče mají různé optimalizace.

Pokud třeba změníte velikost prvku někde dole na stránce, nemusí prohlížeč přepočítávat všechny prvky od hlavičky až po patičku, ale obvykle přepočte velikost a umístění jen prvků v úrovni změněného prvku a všechny pod ním.

Stejně tak některé vlastnosti měnící uspořádání nebo vykreslení stránky mohou být méně náročné než jiné. Třeba změna barvy rámečku (border-color: red) bude rychlejší, než změna barvy pozadí (background: red), kde musí prohlížeč vypočítat prolnutí s textem, nebo změna obrázku na pozadí, kdy je potřeba obrázek správně zmenšit a vykreslit.

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Tato stránka používá Akismet k omezení spamu. Podívejte se, jak vaše data z komentářů zpracováváme..