Jak na kešování souborů skrze .htaccess

Čtvrtek, 16. Únor 2012

Další článek o zrychlování stránek je tu a nyní se naučíme spravovat a využívat kešování souborů na stránkách. Kešování (ukládání do mezipaměti prohlížeče) má zásadní vliv na rychlost načítání stránek. Navíc je to příjemné doplnění k gzip kompresi, o které jsem již psal.

Co je to kešování souborů a k čemu slouží

Pokud to vezmu obecně tak kešování znamená přesunutí často používaných souborů z pomalejšího zdroje na rychlejší. V tomto případě stažení souborů z webu při prvním načtení stránky a následné uložení na disk. Protože disk v počítači je pochopitelně rychlejší než drtivá většina internetového připojení. Z webu se tedy budou stahovat jen soubory, které nechceme kešovat a vše ostatní se bude načítat z disku v počítači.

Asi už chápete, že kešování slouží k tomu, aby se zvýšila rychlost načítání stránek. Pokud tedy chcete bleskově rychlé načítání, využijte kešování.

Proč je načítání do mezipaměti (mimo jiné) důležité?

Ukládání webových souborů do mezipaměti (cache) prohlížeče je užitečné, protože má velký vliv na rychlost načítání stránek, ale to není vše. Šetříme také webový server díky sníženému přenosu dat. Zkrátka pokud nastavíte ukládání do mezipaměti prohlížeče, snížíte tím čas potřebný pro načtení stránky a budete šetřit přenos dat. Server v podstatě skripty, obrázky a CSS styly bude posílat jen novým návštěvníkům při prvním načtení.

Jak tedy provést a začít využívat kešování stránek?

Kešování budeme používat díky modulu mod_expires a zadáním pár řádků do souboru .htaccess. Podporu modulu na hostingu si můžete ověřit PHPInfo souborem. Nahrajete soubor (.php) na stránky a najdete ve výpisu nainstalovaných modulů (Loaded Modules) mod_expires.

Kód do .htaccess pro aktivaci kešování vybraných souborů
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault A600
ExpiresByType text/javascript A31536000
ExpiresByType application/javascript A31536000
ExpiresByType text/css A1209600
ExpiresByType image/gif A1209600
ExpiresByType image/png A1209600
ExpiresByType image/jpeg A1209600
ExpiresByType image/x-icon A1209600
ExpiresByType text/html A1
</IfModule>

Tímto nastavením dáte pokyn prohlížeči, aby si stahoval soubory z lokálního disku (kam si je uložil při prvním načtení). Nebude je tedy stahovat ze sítě a stránky se díky tomu načítají rychleji. Čísla jako A1209600 značí ve vteřinách dobu, po kterou bude prohlížeč stahovat soubory z disku namísto webu. Po vypršení se soubory opět stáhnout ze sítě, uloží do mezipaměti a cyklus se opakuje. Hodnoty doporučuji nastavit na měsíc (2592000). Pokud soubory často upravujete, nastavte si klidně den (86400), týden (604800), ale více jak rok (31536000) rozhodně nedoporučuji.

V tomto konkrétním příkladu je kešování skriptů nastaveno na jeden rok. Styly CSS, obrázky a favicon (x-icon) mají platnost 14 dní. HTML je nastaven na jednu vteřinu (neměňte, HTML se nevyplatí kešovat). Ostatní druhy souborů, které tu nejsou vypsány se ukládají do mezipaměti po standardní dobu (kterou nastavíme v řádku ExpiresDefault).

Jak si ověřit, že mi kešování skutečně funguje?

Funkčnost si můžete ověřit přes jakýkoli nástroj, který zobrazuje HTTP hlavičky. Já používám tento gzip tester. Odešlete tam URL požadovaného souboru a uvidíte (v řádku Cache-Control by měl být ve vteřinách čas do expirace souboru a v řádku Expires jeho datum).

Pokud používáte rozšíření Firebug, přejděte do záložky Síť a aktivujte ji. Potom už jen znovu načtěte své stránky a sledujte, zda jsou soubory, které chcete kešovat zobrazené šedou barvou. To totiž znamená, že jsou čteny z mezipaměti a kešování tedy funguje.

Na co si dávat pozor a závěr článku o kešování

Je třeba brát v potaz to, že soubor zadaný jako jquery.js?ver=1.7.1 a jquery.js není pro prohlížeč totožný! Pokud na stránkách máte oba způsoby zadání skriptu (nebo třeba CSS), uloží se do mezipaměti dvě verze totožného souboru. Jestli se tomu chcete vyhnout, je nejlepší řetězce dotazu odebrat. U webů, které pohání WordPress to uděláte tímto kódem, který vložíte do functions.php používaného vzhledu.

Odstranění zbytečných parametrů z CSS a JS souborů
function _remove_script_version( $src ){
	$parts = explode( '?', $src );
	return $parts[0];
}
add_filter( 'script_loader_src', '_remove_script_version', 15, 1 );
add_filter( 'style_loader_src', '_remove_script_version', 15, 1 );

V dalším článku se podíváme na obrázky. Trochu je poupravíme a budeme se snažit maximálně využít výkonu stránek. Do té doby si zkuste pročíst článek Na co stránka čeká od Dušana. Zaměřte se hlavně na skripty a jejich nepříliš známé parametry defer a v HTML5 nově async, které zrychlují vykreslování a zvyšují tak svižnost stránek (bohužel použití je dost omezené). Napište mi rovněž své připomínky a dotazy ohledně kešování, budu se těšit.

{ Komentáře k článku }

Tomáš Erlich

Udělal jsem pár měření, abych zjistil jak moc je kešování užitečné a o to bych se rád podělil. Jako pokusnou stránku jsem zvolil hlavní stranu tohoto blogu. První načtení trvalo 3.4 sekundy. Další načtení trvalo už jen 1.1 sekundy a to právě díky načítání z mezipaměti prohlížeče (každé měření proběhlo 5x pomocí stejného prohlížeče se stálou rychlostí internetu 1.5 MB – čísla jsou tedy přesná).

Dá se tedy říct, že díky tomuto návodu na aplikaci webové cache můžete dosáhnout více jak dvojnásobné rychlosti načítání. Řečeno přesně… prohlížeči v tomto případě stačí k načtení stránky jen 33 % času, který potřeboval k prvnímu načtení! Paráda ne? :)

Doufám tedy, že článek využijete, pomůže Vám a díky němu už budete vědět jak na to kešování stránek.

Honza

Ahoj,
každý prohlížeč si provádí sám cache. I přes Firebug se mi toto potvrdilo. Měl jsem šedě položky, které již byly v cachi. Tak jsem z toho teď zmaten.

H.

Tomáš Erlich

Ahoj, jsem rád, že se na to ptáš.

Prohlížeč se snaží ukládat soubory do keše, ale je to jen stroj a inteligence moc nemá. Většina prohlížečů kešují jen scripty, protože jsou největší. Dělají to proto, že to má vliv na výkon internetových stránek a hodně lidí na to kašle. Jenže pomocí mod_expires můžeš říct jaký konkrétní soubor se má kešovat a na jak dlouho. Takže můžeš nastavit i kešování obrázků, CSS stylů a dalších souborů.

Proč načítat už jednou stažený obrázek, že?

Navíc je prima využít i gzip. Ten dá povel serveru, soubory se zkomprimují a přenáší se menší objem dat (posílají se k uživateli menší). Věř mi, že všechny ty optimalizace obrázků, zmenšování kódu, zapnutí komprese a kešování souborů se nasčítají a dohromady to dává opravdu velmi (!) znatelný rozdíl.

Jak se můžeš přesvědčit na rychlosti načítání tohoto blogu, ale i zde je pořád prostor pro vylepšení.

Patrik

Tome, děkuju za skvělý článek. Líbí se mně, že píšeš srozumitelně a jasně a ke všemu dáváš příklady. Je to opravdu poučné. Další velké plus máš ode mne za to, že jsi doporučil Honzovi ten úžasný online nástroj, bez kterého se teď na webu nepohnu:) Díky moc!

Tomáš Erlich

Když budeš trpělivý, o obrázcích se v budoucnu rozepíšu více. Ještě si to nechávám v hlavě rozležet, aby to bylo co nejvíce komplexní.

Ale bude tam víc odkazů na nástroje, nějaké obrázky, příklady a hlavně můj názor kde se vyplatí obrázky optimalizovat a kde to už velký smysl nemá. Za pochvalu děkuji, těší mě :).

Olda

Také kešuji hromadně všechny stránky na server (htaccess ve /var/www platí pro všechny domény).
Uvidím, jaký to bude mít časem efekt.
Měl jsem ale problém s favicon, nakonec pomohl typ:
image/vnd.microsoft.icon ostatní mi nevím proč nekešovali.

Tomáš Erlich

Já při prvním aktivování kešování jsem efektu nemohl uvěřit. Stránky se načítaly tak bleskově. Přitom i dnes hromada webů tohle nepodporuje. To je jako přemlouvat uživatele starého IE, aby přešel na Chrome. S favicon problém naštěstí nemám. Používám klasický název favicon.ico a vše se zdá být v pořádku. Ještě jsem se před napsáním komentáře ujistil přes HTTP hlavičky. Hlavně, že jsi to vyřešil. Třeba bude mít někdo stejný problém a díky Tobě má i řešení.

Bender

Mohu otázku? S tématem to souvisí jen velmi úzce. Při spouštění Google Chrome strašně dlouho čekám na první načtení stránky. Ukazuje to „Čekání na mezipaměť“. Co s tím?

Tomáš Erlich

To se mi stává také. Běžně čekám i 2-3 vteřiny. Znamená to, že prohlížeč načíná webové soubory z disku (keše), aby je mohl zobrazit. Když prohlížíš stovky stránek, na disk se ukládají styly, skripty, obrázky a ty pak dají dohromady ohromné množství souborů. Proto disku poprvé trvá dlouho než je načte.

Můžeš to vyřešit tím, že třeba každé dva měsíce vymažeš mezipaměť prohlížeče. U HDD disků je to zpomalení způsobeno taky tím, že jsou soubory rozházené na různých místech po disku. Proto trvá déle než ty správné disk najde. V tomhle případě doporučuji provést defragmentaci přes Defraggler. Je super a zdarma.

O. Brandos

Díky za zajímavý článek.

Hned jsem jej využil a vyzkoušel. Měl bych ale připomínku ke kešování textu/html. Myslím, že tuto část stránky není rozumné ukládat do „keše“. Alespoň ne u pravidelně aktualizovaných webů.

Pokud si totiž budete ukládat (načítat) html do (z) keše, tak týden (měsíc, atd.) nezaregistrujete, že máte na titulce nové články. A ono se jich tam za ten týden třeba nasbíralo 5, 10 atd. Až po týdnu, kdy se vám html zase natáhne ze serveru budete valit bulvy.

Než mě začnete kamenovat tak musím dodat, že jsem to vyzkoušel. Po přidání článku a znovuotevření prohlížeče článek nikde. Asi jen málokdo bude neprakticky tlapkat po F5 – co kdyby? Ale jinak super, ukládání obrázků načítání webu pěkně zrychlilo.

Už se těším na další slíbený článek.

Tomáš Erlich

Ano – kešování html souborů má samozřejmě smysl jen u statických stránek. U všech ostatních je třeba tohle vypnout a dávat si pozor. Proto je v příkladu nastaveno kešování html na jednu sekundu.

Což je v podstatě to samé jako kešování žádné. V tom případě se tak zobrazí aktualizace ihned. Další článek (tentokrát o obrázcích) vyjde s největší pravděpodobností v pátek.

Komentáře jsou pro tento článek již uzavřeny.

Předchozí příspěvek:

Následující příspěvek:

Tato stránka již není udržována. Děkuji za pochopení.