Možností, jak zrychlit načítání webu, je spousty. Cachování obsahu, minifikace skriptů nebo stylů, konkatenace skriptů a stylů, base64 malých obrázků nebo obsahu atd. Pro práci s obrázky je vhodné použití spritů – matice obrázků složená do jednoho velkého obrázku.

Proč sprity
Tím, že se více obrázku spojí do jednoho, dojde k ušetření požadavků na server; existuje pak pouze jeden. Ušetří se také na přenosu dat, když dojde k zacachování obrázku na straně prohlížeče. I přestože se snažíme při kódování používat co nejméně obrázků, někdy není možné se jim zcela vyhnout. Použití spritu je pak vhodné například pokud je nad tagem nastaven efekt na najetí, který vyměňuje obrázky. V tomto případě je obyčejně nutné obrázky přednačíst, aby nedošlo k efektu “probliknutí”. Použitím spritu této komplikované situaci předejdeme díky tomu, že obrázek je jen jeden. Tím pádem je obrázek načten požadavkem na tag bez najetí.

Použití
Pokud má nějaký tag v kaskádovém stylu (nebo Less) použit obrázek na pozadí, je možné skrze pozicování pozadí nastavit zobrazení pouze výřezu z obrázku.
Například:

#home {
width: 46px;
height: 44px;
background: url(img_navsprites.gif) 0 0;
}

Použije se výřez z obrázku img_navsprites.gif o šířce 46px a výšce 44px, a to z levého horního rohu. Více příkladů viz zde. petr-clanek-blog-sprites

Problémy při používání sprite
Pokud je do stylu pro každý tag vložen nový obrázek (klasický přístup), je snadné se v obrázcích orientovat a pro výměnu jednoho obrázku za jiný (pokud zůstává ve stejném rozměru) není nutné zasahovat do kaskádového stylu. Pokud by byl použit sprite a v tagu se obrázek zaměnil za obrázek s jinou velikostí, tak aby nebylo nutné předělat pozice všech ostatních obrázků, musel by se obrázek doplnit na konec a původní ponechat. Takový postup je ale poměrně pracný a neefektivní.

Při implementaci mobilní verze pro našeho klienta se ukázalo, že obrázky nemají kolem sebe žádný ochranný prostor. Pokud je tedy potřebujeme pozicovat uvnitř většího tagu, ukazují se ostatní obrázky ze spritu. Jako řešení jsme tedy doplnili průhledný padding 50 px kolem každého obrázku, aby tak vznikl dostatek manipulačního prostoru. Výsledný sprite měl díky alfa kanálu prakticky stejnou velikost a jednotlivé obrázky pak bylo možné používat i pro větší tagy.

Automatizace
Problém s úpravou spritu poměrně elegantně řeší Node.js, Grunty a preprocesor Less. Pro realizaci je nutné nainstalovat grunt grunt-spritesmith  a grunt-contrib-watch.

grunt-spritesmith
Pro tento task se nakonfiguruje zdrojový adresář, do kterého se nahrávají jednotlivé obrázky ve formátu png určené pro výsledný sprite. Dále je nad adresářem nastaven watcher, který při změně souborů v adresáři spustí task pro vygenerování spritů. Součástí konfigurace je pak cílový Less soubor obsahující proměnné vygenerované z jednotlivých obrázků a mixin pro další použití spritu. Posledními položkami jsou cílový sprite soubor a padding kolem jednotlivých obrázků. Příklad konfigurace tasku:
{
src: ‚src/img/*.png‘,
dest: ‚images/spritesheet.png‘,
destCss: ‚src/css/spritesheet.less‘,
padding: 50,
}
Task při spuštění projde adresář, pospojuje jednotlivé obrázky s daným paddingem (ochranným prostorem kolem), vytvoří sprite soubor v cílovém adresáři a Less soubor s proměnnými podle jednotlivých obrázků. Použití mixinu v Less stylu je pak jednoduché:
&::after {content: “; .absolute; .sprite(@add-to-cart); left: 10px; top: 8px;}
kde .sprite(@add-to-cart) je volání mixinu se jménem obrázku (bez přípony). Tento mixin pak nastaví tagu pozadí a napozicuje obrázek podle nagenerovaných proměnných.

Závěr
Díky použití automatizace grunt tasku dojde k eliminování nevýhod práce se sprity. Je tedy možné bez obav s nimi pracovat a využívat všech jejich výhod – odstranění probliků, snížení zatížení serveru, snížení přenosu dat a díky tomu zvýšení rychlosti načítání webu.

Petr Křížan

Author Petr Křížan

Petr je novým přírůstkem ve vývojovém týmu Shockworks. Specializuje se na optimalizaci a performance internetových obchodů. Má rád nové technologie a nebojí se nových výzev.

More posts by Petr Křížan