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)

Cu FTL (pagina salvata aici)

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.php

Descarcati 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.php

Mutati 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.php

Adaugati 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 …

Comments

10 Responses to “FTL jump … now!”

  1. Razvan Pavel
    on May 19th, 2009 18:23

    chiar cautam ceva simplu de folosit la capitolul asta. thnx vic :)

  2. kleampa
    on May 20th, 2009 07:06

    rulezi !!! mersi

  3. Stefan Alexandru
    on May 20th, 2009 15:53

    Hardcore optimization. Nice! :D

  4. Ovidiu Boc
    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 ;)

  5. Onedesign
    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?

  6. Victor Stanciu
    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 :)

  7. gabriel humeniuc
    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.

  8. Victor Stanciu
    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.

  9. adi Pintilie
    on February 24th, 2010 12:30

    Bun articol / pont, good job dude ! Thanks

  10. Bogdan
    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.

Leave a Reply