FTL jump … now!
Fiecare fisier JavaScript, CSS, imagine, Flash, etc. afisat utilizatorului reprezinta un request catre server. Pentru fiecare asemenea fisier browserul trimite cererea, serverul o preia, proceseaza, serveste fisierul cerut, si tot asa. La site-urile “mari” se simte. In load-ul serverului, in latimea de banda consumata, in experienta utilizatorilor.
Urmand recomandarile echipei de la Yahoo!, o sa va arat la ce solutie am ajuns.
Dar mai intai … cifre. Am ales Okazii.ro drept studiu de caz (toate masuratorile sunt facute cu YSlow, folosind o versiune salvata a primei pagini):
Fara FTL (pagina salvata aici)
- Nota generala in YSlow: E
- Numar request-uri pe prima pagina: 62
- Dimensiune prima pagina: 406.4KB
Cu FTL (pagina salvata aici)
- Nota generala in YSlow: C
- Numar request-uri pe prima pagina: 51
- Dimensiune prima pagina: 226.0KB
Calculat la traficul lor (aprox. 82.000 vizitatori unici pe zi), netinand cont de cache in nici unul din cazuri, asta se traduce in o diferenta de 902.000 de request-uri si 14.1 GB trafic lunar.
Cum se foloseste
Presupunand urmatoarea structura de directoare:
/public
/css
/js
index.phpDescarcati arhiva si extrageti fisierele in root asa incat noua structura va fi:
/ftl
/cache
/lib
CSS.php
File.php
JS.php
config.php
index_css.php
index_js.php
/public
/css
/js
index.phpMutati fisierele index_css.php si index_js.php din directorul /ftl in directorul /public/css, respectiv /public/js, si redenumiti-le in index.php:
/ftl
/cache
/lib
CSS.php
File.php
JS.php
config.php
/public
/css
index.php
/js
index.php
index.phpAdaugati liniile urmatoare in .htaccess:
1 2 3 4 5 6 7 8 | <IfModule mod_expires.c>
ExpiresActive On
ExpiresByType application/x-javascript A315360000
ExpiresByType text/css A315360000
</IfModule>
RewriteEngine On
RewriteRule ^public/(js|css)/([a-z0-9\.]+)\.(js|css)$ public/$1/index.php?hash=$2 |
Includeti fisierele necesare in index.php:
1 2 3 4 | <?php include("ftl/JS.php"); include("ftl/CSS.php"); ?> |
Totul e pregatit, tot ce mai trebuie sa facem e sa incarcam in pagina fisierele. Spre exemplu, ca sa incarc in <head> cateva fisiere CSS si JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php $css = new FTL_CSS(); $js = new FTL_JS(); $css->add('reset') ->add('typo') ->add('layout') ->add('error') ->add('ie', 'lte IE 7'); $js->add('prototype') ->add('sizzle') ->add('effects') ->add('lightbox'); echo $css->render(); echo $js->render(); ?> |
Nu uitati sa setati drepturi de scriere pe subdirectoarele din directorul /ftl/cache.
Codul HTML generat va arata in felul urmator:
1 2 3 | <link rel="stylesheet" type="text/css" media="screen" href="public/css/1e9dd525d1fbe94f7b8aede22cc141f5.1242750618.css" /> <!--[if lte IE 7]><link rel="stylesheet" type="text/css" media="screen" href="public/css/25400724d7370b0b29c9369d9af3dd21.1242750626.css" /><![endif]--> <script type="text/javascript" src="public/js/56c728a5a7689ab1663359a7edff160a.1242751025.js"></script> |
Doua fisiere .css (unul pentru cele standard, unul incarcat doar pentru IE), si un fisier .js. 3 request-uri in loc de 9, si o dimensiune totala de aprox. 6.5 ori mai mica. Fisierele sunt atat minified cat si gzipped, folosind librariile CSSTidy, respectiv Packer
Suna bine, dar ce se intampla cand …
-
Modific sau sterg un fisier .css sau .js ? Trebuie sa schimb ceva de fiecare data ?
Nu. De fiecare data cand un fisier este modificat sau sters, fisierul rezultat este regenerat automat, fara nevoie de interventie.
-
Un utilizator foloseste un browser ce nu suporta Gzip (stone-age style) ?
Respectivului utilizator ii este servita automat o versiune doar minified. Putin mai mare, evident, dar functionala.
-
Structura directoarelor mele nu corespunde cu cea din exemplul de mai sus ?
In directorul /ftl este un fisier config.php unde puteti schimba caile catre fisiere / directoare. Aveti grija numai ca include-urile sa functioneze.
Comments
10 Responses to “FTL jump … now!”
Leave a Reply
Sunt Victor Stanciu, web developer, si scriu despre dezvoltare, standarde, tehnici si tehnologii. (
on May 19th, 2009 18:23
chiar cautam ceva simplu de folosit la capitolul asta. thnx vic :)
on May 20th, 2009 07:06
rulezi !!! mersi
on May 20th, 2009 15:53
Hardcore optimization. Nice! :D
on May 21st, 2009 07:41
ce-nseamna sa aiba omu timp liber :)) bravo tati, asa mai vii de-acasa ;)
da' licenta, unde e licenta ?
partea proasta e ca proiectele la care s-ar preta chestia asta (de la medii in sus) cel mai probabil sunt construite pe alte platforme sau sunt realizate fara a lua in considerare astfel de aspecte de optimizare.
anywayz, congrats ;)
on June 2nd, 2009 17:03
Foarte interesanta ideea. Bun intrebarea despre licenta. Daca se foloseste la aia mari, meriti si tu cativa centi , nu?
on June 2nd, 2009 17:11
Ovidiu nu se referea la licenta in sensul unul mod de a scoate bani, ci ca informatie suplimentara in cod care sa contina si datele mele de contact (email), in eventualitatea cand cineva il foloseste, nu mai stie de unde l-a luat, si are intrebari / sugestii.
Toate jucariile pe care le mai fac si le ofer la download sunt sub licenta MIT, care este cea mai permisiva pe care am gasit-o, si care in principiu spune ca poti face ce vrei tu cu codul, inclusiv sa il vinzi. Nu urmaresc venituri din chestiile astea, le fac fie pentru ca am nevoie la un moment dat de ele, fie ca exercitiu :)
on July 1st, 2009 15:59
Foarte tare modulul.
Are insa o problema (cred). Daca am inteles mecanismul bine in metoda pack, se reciteste de fiecare data data modificarii fiecarui fisier care este inregistrat ca si resursa “internal”. In cazul unui site “mare” cu multe cereri simultane, va genera multe accesuri simultane la HDD.
Intr-un modul similar am considerat suficient ca verificarea necesitatii re-generarii fisierului de cache sa se faca o data la un interval de timp rezonabil (5 min) iar data creeri fisierului este stocata intr-o variabila APC. Cand nu a fost disponibil modului APC am folosit un factor de random de 1 la 100 apelul functiei de regenerare, astfel ca doar la un acces din 100 sa se verifice necesitatea regenerarii cacheului, care pentru un site de trafic mare cred ca este suficient.
Oricum, foarte tare modulul.
on July 1st, 2009 16:07
Salut Gabriel,
PHP face automat cache la rezultatele anumitor functii legate de fisiere (filemtime fiind printre ele).
Gasesti o lista cu toate functiile ale caror rezultate sunt cached automat de catre PHP aici:
http://www.php.net/manual/en/function.clearstatcache.php
Deci filemtime nu va verifica mereu direct fisierul :)
Multumesc.
on February 24th, 2010 12:30
Bun articol / pont, good job dude ! Thanks
on March 9th, 2010 03:23
salut din pacate am un 500 error :( m-ar fi ajutat foarte mult sa ma uit peste codul din aceasta clasa se poate te rog frumos sa imi trimiti un e-mail cu clasa respectiva si exemplul? multumesc anticipat.