Jak vyrobit rychlý web
Internetoví surfaři jsou netrpěliví a neradi čekají. Jak dlouho musí čekat, než se jim zobrazí Váš web?
Mohlo by se zdát, že s nástupem rychlého připojení k internetu je téma rychlého webu možné hodit za hlavu. Ve srovnání s časy vytáčeného připojení je dnes prakticky každý web „rychlý“. Vše je ale relativní. Čím rychlejší je internet, tím méně se lidem chce čekat, takže bez ohledu na rychlost internetu je stále důležité věnovat se rychlosti vlastního webu. S jednoduchým cílem: být co nejrychlejší.

Co se vlastně děje, když uživatel zadá adresu Vašeho webu do prohlížeče a na co se čeká? Aby prohlížeč mohl zobrazit požadovanou webovou stránku, musí učinit následujicí kroky:
- přeložit doménu na IP adresu pomocí dotazu na DNS server,
- spojit se se serverem na dané IP adrese a předložit mu svůj požadavek,
- počkat než server požadavek zpracuje a začne posílat data,
- přijímat zasílaná data dokud nejsou poslána všechna,
- ukončit spojení se serverem a stránku vykreslit.
Tyto kroky musí prohlížeč vykonat nejen pro stažení samotného zdrojového kódu stránky, ale také zvlášť pro každý další potřebný soubor, jako jsou obrázky, soubory s CSS styly nebo JavaScripty. Hlavní roli v určení celkové rychlosti webu tedy hrají dva faktory:
- jak dlouho trvá vyřízení jednotlivých požadavků,
- kolik požadavků je nutné vyřídit, aby byla stránka kompletní.
S narůstající rychlostí internetu nabývá na významu především druhý faktor. Vyřízení jednoho požadavku je typicky rychlá záležitost, zatímco zpracování velkého množství požadavků je naopak typicky pomalé.
Snížení počtu potřebných požadavků
Množství požadavků potřebných pro sestavení stránky v prohlížeči je dáno především počtem obrázků a externích souborů se styly a skripty. V případě souborů se styly a skripty je řešení nasnadě. Sloučit soubory daného typu vždy do jednoho.
V případě obrázků je situace složitější. Je důležité si uvědomit, že se nejedná pouze o obrázky, které jsou přímo součástí HTML jako značka <img>. Jedná se také o obrázky, které jsou využity ke stylování stránky pomocí CSS.
Právě díky CSS stylování ale můžeme počet stahovaných obrázků efektivně snížit. Slouží k tomu tzv. image sprites, což není nic jiného než několik obrázků zkombinovaných do jednoho. Chceme-li pak na stránce na jednom místě zobrazit pouze jeden z nakombinovaných obrázků, použijeme pozicování v CSS a aby se nám na webu nezobrazily i ostatní „přilepené“ obrázky, ošetříme nezobrazování těch částí obrázku, které přesahují stanovené rozměry.
Příklad sprite image (na obrázku vlevo) a jeho použití na webu www.archip.eu:
Ukázka zdrojového kódu CSS šablony:
#build_it_up, #facebook, #cse-search-box {
display : block;
overflow: hidden;
}
#build_it_up {
background: url("../images/archip_sprite.png") no-repeat 0 -136px;
height: 68px;
width: 120px;
}
#facebook {
background: url("../images/archip_sprite.png") no-repeat 0 0;
float: left;
width: 34px;
height: 34px;
}
#search-box {
background: url("../images/archip_sprite.png") no-repeat -68px 0;
float: right;
height: 16px;
width: 16px;
margin: 0;
}
Zkrácení doby načítání
Ačkoliv rychlý internet odsouvá význam doby načítání jednoho souboru do pozadí, stále se jedná o důležitý aspekt, který může významně přispět k uživatelskému pohodlí.
Zmenšení velikosti souborů
Celkem logicky platí, že doba načítání je tím kratší, čím menší soubor posíláme. Ve zdrojových kódech HTML, CSS či JavaScriptů bývá typicky hodně „vaty“, která tam být vůbec nemusí. Jedná se především o tzv. bílé znaky, tedy mezery, tabulátory a zalomení řádků. Ty tam píše programátor či kodér z toho důvodu, aby se v textu dobře vyznal. Prohlížeč ale není programátor a vyzná se i v neorganizovaném kódu, pokud je správně napsaný. Vyplatí se proto tyto zdrojové kódy po jejich napsání tzv. minifikovat = odstranit z nich všechny nepotřebné znaky. Oproti původní velikosti souboru můžeme ušetřit klidně i 20%.
Podobným způsobem lze redukovat i velikost obrázků. U obrázků ve formátu JPEG hraje hlavní roli nastavení kvality komprese, což je číslo od 0 do 100. Čím vyšší kvalita, tím větší soubor. Sami si ale můžete vyzkoušet, že rozdíl mezi kvalitou 90 a kvalitou 100 prakticky nelze zrakem rozpoznat a jediný rozdíl je tak ve velikosti souboru, která může narůst i dvojnásobně. U obrázků ve formátu GIF či PNG (ale pro JPG to platí také) lze velikost souboru zmenšit správným nastavením použité barevné palety. Ideální je taková barevná paleta, která obsahuje pouze ty barvy, které v obrázku skutečně používáme.
V OpenSource aplikaci pro úpravu obrázků GIMP můžete použitou barevnou paletu snadno zredukovat pomocí tzv. převodu na indexované barvy. Ten najdete v menu Obrázek → Režim → Indexovaná, kde pak v dialogovém okně vyberete možnost „Generovat optimální paletu“. Kvalitu obrázku ve formátu JPEG pak nastavíte přímo při ukládání obrázku, editor se Vás na požadovanou kvalitu sám zeptá.
Komprese souborů
Protokol HTTP ve verzi 1.1 umožňuje využívat komprese souborů podobně jako jí známe například z archivů ZIP či RAR. Podmínkou pro její použití je, že se na tom server s prohlížečem ještě před zasláním souboru dohodnou. V praxi to vypadá tak, že prohlížeč při dotazu na server uvede že má zájem i o soubor komprimovaný a server, pokud to umí, mu soubor komprimovaný zašle. V řeči HTTP hlaviček to vypadá následovně:
Dotaz prohlížeče, který říká že by se mu líbily soubory komprimované metodou gzip nebo deflate:
GET / HTTP/1.1
Accept-Encoding: gzip,deflate
Odpověď serveru, který požadovaný soubor zkomprimoval metodou gzip:
HTTP/1.1 200 OK
Content-Encoding: gzip
Ke zprovoznění komprese souborů na HTTP serveru Apache lze s úspěchem využít standardní modul mod_deflate, který ve výchozím nastavení dokáže soubory komprimovat nejběžnějšími metodami gzip a deflate. Tyto metody podporují prakticky všechny moderní prohlížeče.
Kešování
Veškerá snaha o minimální množství požadavků a co nejkratší načítání má své hranice. Chceme-li na webu obrázky, alespoň jeden požadavek na obrázek asi potřebovat budeme. Přesto je zde stále ještě jedna cesta ke zrychlení webu a tou je tzv. kešování.
Většinou to bývá tak, že soubor se styly, soubor se skripty a obrázky tvořící „design webu“ se používají na všech stránkách webu stejné. V takovém případě je samozřejmě na místě otázka, proč by si měl prohlížeč pro každou stránku tyhle věci stahovat znovu a znovu, když jsou všude úplně stejné? Řešením je kešování souborů.
Kešování (z anglického cache – zásobárna) znamená ukládání stažených souborů někde, odkud je načteme rychleji než z původního zdroje. Nejlépe přímo v počítači, ze kterého stránky prohlížíme. Všechny moderní prohlížeče tuto možnost podporují. V případě, že je na některé další stránce znovu použit stejný soubor, který je již v keši uložený, použije se ten. Aby ale prohlížeč nenabízel zastaralé soubory, které už na serveru dávno vypadají jinak, musíme prohlížeči říct, jak dlouho si takové soubory smí nechat a zda tak vlastně vůbec muže dělat. K tomu slouží hlavičky HTTP protokolu Cache-Control a Expires.
Cache-Control: max-age=86400
Expires: Thu, 03 Mar 2011 19:49:42 GMT
Obě hlavičky prohlížeči říkají, jak starý maximálně může soubor být (max-age), respektive kdy nejpozději musí být nahrazen „čerstvou“ verzí ze serveru (Expires).
V jazyce PHP tyto hlavičky odešleme jednoduše pomocí příkazu header():
<?php
$offset = 60 * 60 * 24; //expirace jeden den vyjadrena v sekundach
header( 'Cache-Control: max-age=' . $offset );
$expires = 'Expires: ' . gmdate('D, d M Y H:i:s', time() + $offset) . ' GMT';
header( $expires );
?>
Nastavení správné doby „trvanlivosti“ jednotlivých souborů je velice citlivá záležitost. Doba nesmí být delší, než je typický interval obměny souboru. U obrázků, videí, flash animací či různých souborů ke stažení (PDF, DOC, MP3 apod.) se dá s velkou pravděpodobností předpokládat, že se po umístění na web už nikdy měnit nebudou, nebo jen velmi sporadicky. V takovém případě lze nastavit dobu expirace dlouhou. Expirace dlouhá jeden týden bývá v takových případech zcela běžná, v některých případech i mnohem delší (například jeden rok, což znamená že i po roční pauze Váš prohlížeč nebude muset znovu daný soubor stahovat a jednoduše jej vezme z vyrovnávací paměti, pokud tam ještě je). U souborů CSS nebo JavaScriptů je pravděpodobnost změny o něco větší, ale také nikterak závratná. Expirace dlouhá jeden den je zde naprosto v pořádku. K nastavení intervalů podle toho o jaký typ souboru se jedná, slouží v případě HTTP serveru Apache modul mod_expires. Ten umožňuje určit expiraci pro libovolný typ souboru (tzv. MIME typ) zvlášť.
V některých případech si nemusíme být vůbec jisti tím, jak dlouho může být daný soubor „čerstvý“ na straně prohlížeče. To se týká hlavně samotného HTML kódu stránky. Ta může být klidně i mnoho dní zcela stejná, ale také se tam může objevit například nový příspěvek v návštěvní knize a najednou už je kód potřeba aktualizovat. V takové situaci nám pomůže opět protokol HTTP a jeho stavové kódy. Prohlížeč se zkrátka zeptá serveru, zda se soubor už náhodou nezměnil a pokud ne, použije ten, který už má. Aby server poznal, jak starou verzi souboru prohlížeč má a zda je stejná, jako ta aktuální, je zapotřebí jednotlivé verze nějakým způsobem odlišit. Nejjednodušší je odlišení pomocí data poslední změny. Prohlížeč se tedy zeptá serveru, zda se soubor od té doby, kdy si ho naposledy stáhl, nezměnil:
GET /obrazek.jpg HTTP/1.1
If-Modified-Since: Wed, 02 Mar 2011 15:38:07 GMT
A pokud se nezměnil, server odpoví zvláštním stavovým kódem 304 a soubor prohlížeči vůbec nepošle:
HTTP/1.1 304 Not Modified
K odlišení jednotlivých verzí souboru lze kromě data poslední změny využít i tzv. Etag. To je speciální hlavička, která obsahuje řetězec unikátní pro danou verzi souboru. Server ji vždy vytvoří na základě konkrétního obsahu souboru a při každé jeho změně ji přepočítá a změní. Prohlížeč se pak může dotazovat, zda na serveru existuje soubor s touto hodnotou Etag.
Při prvním získání souboru server zašle prohlížeči aktuální hodnotu Etag:
HTTP/1.1 200 OK
Etag: "3802a4-16fe-49d81c367cd63"
Prohlížeč se pak při opakovaném použití souboru zeptá, zda je tato verze stále platná:
GET /obrazek.jpg HTTP/1.1
If-None-Match: "3802a4-16fe-49d81c367cd63"
V případě, že platná je, odpoví server opět stavovým kódem 304. Etag má oproti datu poslední změny tu výhodu, že dává prohlížeči i serveru větší jistotu, že soubor je skutečně zcela stejný.
Pokud si nepřejeme, aby prohlížeč daný soubor kešoval, stačí správně nastavit hlavičku Cache-Control:
Cache-Control: no-cache
Shrnutí
Pro vytvoření opravdu rychlého webu stačí:
- sloučit soubory se styly CSS a soubory s JavaScripty,
- minifikovat tyto soubory a také zdrojový kód stránky v HTML,
- vhodným způsobem zkombinovat použité obrázky do image sprites,
- zredukovat velikost použitých obrázků správným nastavením kvality a barevné palety,
- zprovoznit na serveru kompresi souborů,
- nastavit na serveru správné zasílání hlaviček Cache-Control a Expires
- nastavit na serveru zasílání hlavičky Etag a správné odpovídání stavovým kódem 304.
Pokud byste si chtěli ověřit, jak moc Váš nebo cizí web odpovídá požadavkům na rychlý web, můžete k tomu využít plugin PageSpeed pro prohlížeč Firefox:
Tento plugin zkontroluje všechny zde uvedené parametry a ještě spoustu dalších a poradí Vám, co můžete zlepšit. K jeho fungování je zapotřebí mít nainstalovaný plugin FireBug: