PHP oldalak sebességének javítása

Feltételes beillesztés

Gyakori programozói probléma, hogy egy több oldalból álló site minden oldalán minden szokásos fájl beinclude-olunk, még akkor is, ha nincs rá éppen szükség. Ha másképp nem nézzük meg a futások során, hogy milyen feltételek kellenek ahhoz, hogy egy fájlt beillesszünk a programba és csak ekkor illesszük be.

Ne akarjunk kiszolgálni teljes HTML tartalmat PHP-val.

Bár a PHP nyitó és záró tagjén kívül eső tartalom átfut a PHP-n változtatás nélkül, de mégis időt tölt vele az értelmező. Az is bolondság, ha ritkán használt több sornyi statikus HTML kódot állítunk elő a PHP segítségével. Itt a sebességet úgy kell mérlegelni, hogy a külön fájlban lévő include beolvasása lassítja-e a kódot vagy a statikus HTML beírása a kódba. Általában is egészséges a statikus tartalmat és a PHP kódot kettéválasztani.

Bár sok olyanról lehetne beszélni, ami általában nem a PHP, hanem programozási elméleti és gyakorlati kérdés, de ennek a cikknek nem az a célja, hogy a fejlesztőket megtanítsam általánosan optimális kódot írni, ezért itt a szerver oldali lehetőségek végére is értem.

A WEBFejlesztő lehetőségei

Ennek a kérdésnek a megválaszolására a Yahoo-tól származó válaszok vannak. először is az oldalunk sebességét célszerű mérni. Erre a célra telepítsünk fel a Firefox-ot (ami a Fejlesztők barátja), tegyük fel a Firebug és az YSlow kiterjesztéseket. Utána nézzük meg, hogy kedvenc WEB oldalunk miért lassú.

A Yahoo az alábbi pontokban foglalta össze a kliens által érzett sebesség érzésének javításának lehetőségeit:

Kevesebb lekérdezés legyen

A lekérdezések számát egy adott oldalon a css és a javascript file-ok számával lehet csökkenteni. Erre célszerű olyan alkalmazást alkotni, amely összefésüli a javascript fájlokat és a css fájlokat egy-egy "nagy" fájlba. Drupal esetén az admin/settings/performance oldalon adhatjuk meg, hogy a Drupal összefésülje-e a CSS oldalunkat. Más oldalakon kézzel is összefésülhetjük őket. lehet olyan PHP alkalmazást írni, amely automatikusan előállítja a szerver oldalon az ered? css fájlokból az egyet. A Javascript fájlokat is össze lehet rakni akár kézzel is. A Drupal esetén a javascript aggregator modul használatát is javaslom.

Használj elkülönült URL-t a statikus és a dinamikus oldalak kiszolgálására

Már az is gyorsít, ha két szervert futtatunk a vason, két különböző porton és az egyik csak a dinamikus oldalakat, a másik a statikus oldalakat szolgálja ki. Drupal esetén javaslom a Drupal integration modul-t. A két szerver közül a statikus tartalmat kiszolgáló lehet például a LightHTTPD is.

Használj CDN (=Content Delivery Network) szerverrendszereket.

Ezek a szerverrendszerek a világban szétszórva helyezkednek el és a lekérdezésekre mindig a földrajzilag legközelebbi szerver válaszol. Bebizonyosodott, hogy a webes tartalmak 80-90%-a kép, flash és ehhez hasonló állandó tartalmakból áll. Ezekre a tartalmakra jellemző a viszonylag nagy fájlméret és a ritka változás. Az ilyen tartalmakat jól kiszolgálják a CDN-ek. Ilyen CDN-ekkel néhány nagy szolgáltató rendelkezik, mint például az Akamai Technologies, Mirror Image Internet, vagy a Limelight Networks. Viszonylag olcsón biztosítanak tárhelyet bizonyos szolgáltatások használatához.

Használjuk az Expires vagy a cache-control header bejegyzést a fájlokban

Az Expires header a böngésző cache-t utasítja arra, hogy meddig használja a helyben tárolt tartalmat az oldalak letöltésekor. Ez az érték gyakran nem több pár napnál. Olyan oldalak esetében, amelyek statikusnak mondhatók ezt az értéket a távoli jövőre érdemes állítani. A parancsokat PHP-ból a header függvénnyel lehet könnyen előállítani:

header("Expires: Thu, 15 Apr 2010 20:00:00 GMT");

Apache szerver esetén meg lehet adni a ExpiresDefault parancsot az Apache konfigurációs fájljában, ami a lekéréshez képest állítja a cache lejáratának időpontját. Az alábbi példa 10 éves lejárati időt határoz meg.

ExpiresDefault "access plus 10 years"

A távoli jövőben lejáró fájlok azonban változás esetén továbbra is maradnak, ezért célszerű verziószámmal ellátni a változó fájlokat, vagy dinamikus tartalom szolgáltatásnál a fájlnevet módosítani kell egy GET paraméter asználatával. A headerek kiadását Apache esetén a .htaccess és a mod_expires modul használatával lehet megoldani vagy olyan szerver oldali alkalmazással, ami automatikusan mindig más paramétert helyez egy get kéréssel a fájl nevébe.

GZIP használata

Ma már minden böngésző ismeri a gzip tömörítés lehetőségét és az átküldött anyagot ki is tudja bontani. Ez a kisebb sávszélesség foglalást eredményez. A HTML fájlok átlagosan 50% körüli tömörítést tudnak hozni. A Drupal a cache bekapcsolásakor gzip formában tárolja az adatokat. Az Apache szervert is rá lehet venni a tömörítésre az alábbi paranccsal a .htaccess vagy a httpd.conf fájlban:

AddOutputFilterByType DEFLATE text/css application/x-javascript

Ez tömöríti a javascript és css fájlokat is.

Apache 2.x hasznája a mod_deflate modult erre a célra.

A HTTP/1.1, web kliensek elküöldik a szervernek az alábbi fejlécet a http kéréskor:

Accept-Encoding: gzip, deflate

A WEB szerver pedig ebből tudja majd, hogy melyik tömörítési formát képes lekezelni a kliens, és elküldi a válasz fejlécében a tömörítés formáját.

Content-Encoding: gzip

Tegyük a CSS hívásokat a HTML oldal tetejére

Ha a HEAD részbe tesszük a css hívásokat, akkor az oldal sokkal gyorsabban fog letöltődni és renderelődni, és ne felejtsük el, hogy lehetőleg egy CSS fájl legyen minden oldalon, hogy kevesebb legyen a szerverhívás!

Tegyük a javascript hívásokat az oldal végére.

A javascript hívások az egyes speciális eseteket leszámítva (onload, dinamikus tartalom a js által kiszolgálva) akkor indulnak el, amikor a letöltött oldalon valami eseményt generálunk. A letöltés során ezek gyakran semmiféle tartalmat nem szolgáltatnak, csak egyfajta inicializálásként és függvénytárként léteznek. Ha a </body> vagy még jobb, hogyha a </html> tag elé tesszük közvetlenül ezeknek a fájloknak a behívását, akkor ezek akkor futnak csak le, amikor már az oldal kirajzolódott.
Drupal esetén általában meg lehet tenni azt, hogy a a footerbe helyezzük át a js hívásokat. A default esetben ilyet kell beállítanunk a page.tpl.php oldalunkon:

    <?php print $scripts ?>
    <?php print $closure ?>
  </body>
</html>

Kerüljük a CSS kifejezéseket

A CSS kifejezéseket a böngésző kiértékeli az oldal betöltésekor, átméretezésekor és görgetésekor is.

A CSS és javascript fájlokat vegyük ki az oldalakból

A stílus és javascript kódokat külön fájlokba téve ezeket a fájlokat a böngészők cache-elik, tehát a lekért adatmennyiség és a HTTP kérések száma is csökken.

Csökkentsük a DNS kérések számát

Gyakori manapság, hogy az oldalainkon a Yahoo, a Google, vagy más szolgáltató által adott widget-eket, kis alkalmazásokat használunk az oldal feldobására. Minden külső hivatkozás lassítani fogja az oldalunk elérhetőségét. Ha mégis szükségünk van rá, akkor a lehető legtöbb fájlt töltsük le a szerverünkre, (css, js, statikus html) és onnan szolgáljuk ki őket.. Google Analytics használata és Drupal esetén például a Google Analytics modult telepítsük, ami a lokális gépen cache-eli a megfelelő fájlokat.

Csökkentsük a Javascript fájlok méretét.

Erre a célra lehet találni a neten megfelelő alkalmazásokat, azonban azok az alkalmazások, amelyek nem csak csökkentik a fájlméretet, hanem obfuscatorként is működnek (összezavarják a kódot, hogy nehéz legyen visszafejteni) gyakran okoznak gondot a js részek működésében. Ilyen programok pl. JSMIN PHP implementation vagy http://dean.edwards.name/packer/.  A Googleban a javascript compressor kifejezésre keresve több ilyen alkalmazást lehet találni.

Kerüljük az átirányítások használatát

Ne legyenek duplán elérhető oldalak, mert a keresők azt nem szeretik.

Töröljük a duplán betöltött scripteket.

Gyakori az olyan fejlesztés, amikor egy modul betölt javascript fájlokat, pl prototype vagy jquery, amelyek az adott modulhoz szükségesek, de minden modul a saját példányát tölti be. Ilyenkor nyilvánvalóan lassulnak a szolgáltatások, ráadásul ki is üthetik egymást az alkalmazások. A Drupal-ban a drupal_add_js()függvény elee megoldja a problémát, ugyanis segítségével elkerülhető a többszörös betöltés.

Konfiguráljuk be az ETag paramétert.

Ez a tag az apache-ban egyedileg azonosítja a szerveren lévő fájlt. A kéréskor ezt az azonosítást használja az azonosság kifejezésére. Egy hoston több virtuális szerver használata esetén ezt tiltani kell. Ezt az apache-ban az

 FileEtag none

paranccsal tehetjük meg az apache konfigurációs fájljában.

Az Ajax kéréseink legyenek cache-elhetők.

Ez a feltétel gyakran teljesül az által, ha a szerver oldalon gzip-pel küldjük ki az információkat. A GZIP tömörítés egy átlagos oldalon kb. 50%-ot elér, tehát kétszer olyan gyorsan tölt?dik le a szerverről, mint tömörítés nélkül.

További hasznos cikkek a Weboldalak gyorsítása témában

Yahoo cikk a weboldalak gyorsítása témában