Kategória: Návody Joomla

Zmenené: 8. apríl 2009

Optimalizácia stránky

Pri hraní sasa s jedným modulom som sa oprašoval a aktualizoval vedomosti o PHP a popri tom som narazil na webový nástroj Web Page Analyzer. Samozrejme, že som ho hneď vyskúšal az hrôzou zistil, že moja hlavná stránka má skoro 400 kB. Myslím si, že to je veľa, tak som sa tým začal zaoberať hlbšie a čo som okolo toho zistil možno pomôže aj iným.

Túto stránku mám založenú na redakčnom systéme Joomla! 1.5.x. Používam vlastnú úpravu šablóny, ktorá vychádza z RockWebify (ešte pre Joomla 1.0) a mnoho rôznych rozšírení. V šablóne mám nastavené východzie použitie MooTools, vrátane ToolTipov. Toto zhrnutie nepíšem aby som sa chválil, ale aby som dal najavo, že s inou šablónou a inou sadou rozšírení môžete dostať celkom iné výsledky. Všetky optimalizačné nastavenia Joomly a jej rozšírení som mal nastavené na východzie hodnoty (moje hranie sa s Joomlou ma prinútilo k úplnej reinštalácii pár dní pred vydaním verzie 10).

Upozornenie

Používanie nástroja Web Page Analyzer je jednoduché, do okienka Enter URL to diagnose treba zadať adresu webovej stránky, v mojom prípade slavino.sk. Ako si pozornejší iste všimli, netreba udať ani protokol (http) tým sa nikdy nič nepokazí. Samozrejme, odoslať kliknutím na tlačítko odeslat (ja ho mám lokalizované), v nasledujúcom okne zadať captcha a potom už len chvíľu počkať (pozeral som teraz čas, je to viec ako štyri minúty).

Prvý test

Pri prvom spustení analyzátora som zistil, že stránka má spolu 85 prvkov (Total HTTP Requests: 85) a spolu to robí 398 113 B (Total Size: 398113 bytes). Toto zistenie ma, mierne povedané, prekvapilo a začal som pátrať, čo všetko to tvorí súčasť mojej stránky. Analyzátor k tomu poskytuje krásnu prehľadnú tabuľku, kde sú všetky prvky stránky zoradené podľa veľkosti. Pričom ku každému prvku ukazuje jeho typ (napr. CSS, či IMG), odkaz na prvok a krátky popis, vrátane informácie koľko možno ušetriť komprimáciou. V tejto tabuľke som zistil, že mám v definícii CSS šablóny dve chyby. Obe boli odkazy na neexistujúce obrázky. Jeden odkaz som zmazal, keďže to bol starý pozostatok, na ktorý som zabudol. A druhý obrázok som doplnil, to zase bola chyba v XML súbore, pre ktorú nebol obrázok prekopírovaný na stránku.

Ako ďalší krok som sa zameral na veľkosť obrázkov, ktorá podľa mňa bola príliš veľká. Použil som na to nástroj optipng, ktorý je súčasťou distribúcie Debian (ale nainštalovaný som ho nemal), spolu s prevodom obrázkov šablóny a hlavnej stránky na indexované farby (všade kde to šlo bez straty kvality). Tieto úpravy priniesli úsporu, ktorú som ani nečakal.

Druhý test

Po oprave CSS a úprave obrázkov som teda spustil test znova a výsledok ma milo prekvapil, pretože analyzátor tentokrát nameral celkovú veľkosť stránky 298 039 B (ono viac ako 50 kB mi urobil jeden obrázok). V tomto okamžiku som už vedel, že ďalšiu optimalizáciu grafiky robiť nebudem, tak som sa pozrel, čo mi to tú veľkosť robí teraz. Ako prvý (teda najväčší) prvok je uvedený súbor mootools.js, s udávanou veľkosťou 74 404 B. Inými slovami, skoro štvrtinu veľkosti tvorí jeden súbor, pričom analyzátor tvrdí, že až 54 156 B možno ušetriť jeho komprimáciou.

Preto som svoje ďalšie úsilie zameral práve na minimalizáciu JavaScriptu. Vyskúšal som rôzne webové nástroje na komprimáciu, až som nakoniec zmenšil tento súbor na približne 30 kB. Analyzátor však stále tvrdil, že komprimáciou ho možno zmenšiť na približne 20 kB. Vyskúšal som teda jeho komprimáciu prostredníctvom PHP (priznám sa, že neúspešne), ale túto cestu som nakoniec zavrhol. Najmä keď som si predstavil, že túto úpravu pomocou PHP by som musel robiť pre každý javaScriptový súbor rôznych rozšírení a potom vždy znova pri ich aktualizácii, bol som si vedomý, že tade cesta nevedie.

Rada

Rovnako neúspešne som sa pokúšal komprimovať súbory CSS, ale z rovnakých dôvodov som to vzdal ešte pred úspešným zakončením.

Zápis k súboru mootools.js vyzeral takto:

74404 [B] SCRIPT http://slavino.sk/media/system/js/mootools.js Header size = 227 bytes Up to 54156 bytes could have been saved through compression.

Komprimácia na strane servera

Pri hľadaní riešenia som narazil na článok Compressing files on Apache with mod_deflate, ktorý popisuje ako presvedčiť server Apache, aby robil komprimáciu príslušných súborov a vedel som, že je to čo hľadám. Pretože namiesto nastavovanie komprimácie jednotlivých súborov je možné serveru nariadiť aby komprimoval súbory určitých typov. A najkrajšie je, že je mu to možné nariadiť aj prostredníctvom súboru .htaccess, keďže na hostingu ku konfiguračnému súboru prístup nemám.

Prvá otázka, ktorú treba zodpovedať, je: Podporuje server komprimáciu? Na toto som už mal odpoveď z predchádzajúceho pokusu a použil som na to jednoduchučký PHP skript:

if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'))
   echo "ob_gzhandler funguje";
else
   echo "ob_gzhandler nefunguje";

echo "< br>< br>";

if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate'))
   echo "deflate funguje";
else
   echo "deflate nefunguje";

Keďže mi server v oboch prípadoch napísal, že server uvedené veci podporuje, mohol som pristúpiť k ich nastaveniu. Na samotné nastavenie som použil súbor .htaccess môjho koreňového priečinka na hostingu (ktorý sa líši od priečinka DOCUMENT_ROOT), ale pokojne je možné tieto nastavenia použiť v súbore .htacces aj v koreni Joomly. Ak používate mod_rewrite na prepisovanie SEF adries, možno tieto voľby pridať priamo do tohoto súboru.

Predmetné nastavenie používa direktívu AddOutputFilterByType, ktorej pošlem filter DEFLATE (poskytovaný modulom mod_deflate) nasledovaný príslušným typom súboru, na ktorý má byť komprimácia aplikovaná. Len poznamenám, že všetky požadované typy súborov možno poslať v jednom riadku, ale ja dávam prednosť rozpísaniu na jednotlivé riadky. Takže som do súboru .htaccess pridal riadky:

AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/x-js
AddOutputFilterByType DEFLATE text/css

Týmto nastavením nariaďujem serveru posielať komprimovane všetok obsah, ktorý je zadaných MIME typov. Použitie tejto direktívy môže niekedy spôsobovať problémy, najmä ak MIME typ nie je správne rozpoznaný, nebude komprimácia použitá. Presne s týmto problémom som sa stretol.

Keď som spustil analyzátor s týmto nastavením, tak som zistil, že CSS súbory sú komprimované:

3675 CSS slavino.sk … bify-red/css/template.css Header size = 255 bytes Congratulations! This file was compressed.

S tým som bol určite spokojný, ale stav JS súborov sa nezmenil. Ako som neskôr zistil, bolo to práve kvôli inému MIME typu, ktorý som si zistil pomocou nástroja lynx:

lynx -head -dump http://slavino.sk/media/system/js/mootools.js
HTTP/1.1 200 OK
Date: Wed, 01 Apr 2009 19:08:53 GMT
Server: Apache
Last-Modified: Sun, 29 Mar 2009 22:05:16 GMT
ETag: "6eefc-9b48-4664929285f00"
Accept-Ranges: bytes
Content-Length: 39752
Connection: close
Content-Type: application/x-javascript

Serverom hlásený MIME typ som zvýraznil tučne na konci výpisu. Prosto stačilo v definícii v .htaccess zmeniť text/x-js na application/x-javascript a všetko začalo fungovať ako má. Spomínaný mootools.js sa naozaj zmenšil na sľubovaných cca 20 kB:

20329 SCRIPT http://slavino.sk/media/system/js/mootools.js Header size = 272 bytes Congratulations! This file was compressed.

Celková veľkosť stránky klesla na 171 775 B (Total Size: 171775 bytes), čo je približne 40 % pôvodnej veľkosti a s touto veľkosťou som už spokojný.

Iný spôsob komprimácie

Spomínal som problémy so správnym rozpoznaním a určením MIME typu súboru, ktoré môžu viesť k upusteniu od komprimácie. Tento problém je popísaný v dokumentácii direktívy, kde ju označujú za zastaranú (deprecated) a radia použiť direktívu AddOutputFilter, ktorá priraďuje rovnaký filetr, nie však na základe MIME typu súboru, ale na základe prípony súboru, takže komprimácia súborov s kaskádovým štýlom a JavaScriptu zaistia direktívy (na rovnakom mieste):

AddOutputFilter DEFLATE css
AddOutputFilter DEFLATE js
AddOutputFilter DEFLATE txt
AddOutputFilter DEFLATE xml
AddOutputFilter DEFLATE html
AddOutputFilter DEFLATE php

Čím je problém so správnym rozpoznaním MIME typu vylúčený.

Varovanie

Nepridávajte komprimáciu už raz komprimovaných obrázkov (JPG, PNG, GIF), pretože to je zbytočné. Získaný komprimačný pomer je nízky a za istých okolností môže byť komprimovaný obrázok väčší ako pôvodný…

Ďalšie vylepšenia .htaccess

Komprimácia je jedna vec. Zmenšenie veľkosť stránky nie len zmenší sieťovú prevádzku (traffic), ktorý majú mnohí na hostingu meraný, ale hlavne zrýchli načítanie stránky v prehliadači návštevníka. A toho by malo ísť hlavne. Tomuto rýchlejšiemu načítaniu sa dá napomôcť aj nastavením ukladania niektorých častí do vyrovnávacej pamäte (cache cachovania) v prehliadači. Buďme však k sebe úprimní, koľkí dnešní používatelia o tejto možnosti vedia? Ja osobne neviem kde sa to nastavuje v IE a či sa to tam vôbec nastaviť dá.

Našťastie je možné túto informáciu poslať priamo zo servera, a tak urobiť časť práce za návštevníka. Pomôže opäť spomínaný súbor .htaccess a niekoľko direktív, a to ExpiresActive, ExpireByType a ExpiresDefault. Ich popisom sa zdržiavať nebudem, nájdete ho na uvedených odkazoch, preto priamo môj príklad, ktorý nastavuje cachovanie na jeden deň pre JavaScriptové súbory a jeden mesiac pre obrázky:

ExpiresActive On
ExpiresByType application/x-javascript A604800
ExpiresByType image/gif A2419200
ExpiresByType image/jpg A2419200
ExpiresByType image/png A2419200
ExpiresDefault "modification plus 1 day"

A nemali by sme ani zabudnúť, že nie všetky prehliadače komprimáciu podporujú, preto ju pre niektoré vypnime, respektíve obmedzme:

BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

Záver

Čo dodať na záver. Pevne verím, že uvedený spôsob pomôže nielen návštevníkom, ale aj mne, pretože nemusím komprimovať jednotlivé súbory, ale veselo využívať výhody zníženého prenosu dát.