HTTP zahtevi za slikama iz CSS fajla

Nedavno sam primetio jednu čudnu stvar – ukoliko se link do jedne iste slike nekoliko puta ponavlja u CSS fajlu, Firefox (a verovatno i drugi) neće napraviti jedan HTTP upit do te slike, već onoliko upita, koliko se puta taj isti link ponavlja u tom fajlu. Zvuči neverovatno da se prilikom parsiranja CSS fajla ne vodi računa o već poslatim zahtevima, jer takva optimizacija može biti uvedena uz svega par linija koda i sprečiti nepotrebne zahteve i zauzeće resursa. No, kako bilo, ostaje na nama da se potrudimo da ubrzamo naš sajt drugim metodama.

Ukoliko ste se bavili optimizacijom sajtova, verovatno ste naleteli na dobro poznate savete od Yahoo-a i prvi među njima savet za smanjenje broja HTTP zahteva. Kombinovanje više sličica u jednu i prikazivanje delova te kombinovane slike preko koordinata (background-position u CSS-u) ima svoje ogromne prednosti.

Uzmimo za primer da na stranici imamo tri liste sa tri različite sličice za strelice. Kombinovanjem, tri sličice možemo spojiti u jednu.

U CSS fajlu je takođe veoma jednostavno podesiti putanje do sličice, i koordinate za svaku listu posebno. Ujedno, CSS kod sličan ovome se može videti na mnogim sajtovima širom interneta, recimo A List Apart – CSS Sprites ili Image Sprite CSS Navigation.

ul {
list-style-type:none;
}
ul li {
padding-left:15px;
}
ul#black li {
background: #fff url("arrows.jpg") no-repeat left 6px;
}
ul#blue li {
background: #fff url("arrows.jpg") no-repeat left -14px;
}
ul#green li {
background: #fff url("arrows.jpg") no-repeat left -34px;
}

I ako je to putanja do iste sličice, sa ovakvim kodom možemo samo pogoršati situaciju. Naš browser će poslati tri zahteva za istom sličicom i download-ovaćemo tri iste slike. Pošto je kombinovana slika većih dimenzija i veće težine od svake pojedinačne, jasno je da se ovakvom metodom uvećava protok podataka za 3 puta.

Rešenje ovog problema je veoma jednostavno i treba samo jednom “pozvati” tu sličicu, a poziciju im podesiti, za svaku listu posebno.

ul {
list-style-type:none;
}
ul li {
padding-left:15px;
}
ul#black li, ul#blue li, ul#green li  {
background: #fff url("arrows.jpg") no-repeat;
}
ul#black li {
background-position: left 6px;
}
ul#blue li {
background-position: left -14px;
}
ul#green li {
background-position: left -34px;
}

Možete pogledati i primere neoptimizovanog koda i optimizovanog, koji koriste različite CSS fajlove.

Dodatak: Kako videti i analizirati HTTP zahteve?

Postoji mnoštvo softvera koji omogućavaju skeniranje protoka na mrežnom adapteru računara. Moguće i najbolji među njima je Wireshark, koji može da analizira sve protokole.

Web programerima će sigurno dosta zanimljiviji biti plugin za Firefox – Live HTTP Headers. A evo i rezultata iz njega na kome se više nego jasnije vidi rezultat optimizacije.

Na tabu “Headers” možete videti kompletne GET I POST zahteve, sa headerom, kao i kompletne odgovore servera. Na tabu “Generator” se nalaze samo uprošćeni zahtevi, bez headera. Trebate samo imati u vidu da se sličice keširaju na lokalnom računaru i da ukoliko ste već posetili neku stranu, verovatno je da  zahtevi se neće pojaviti. CTRL+F5 daje realnu sliku.

3 Comments

  1. Interesantno. Meni ovo nikad ne bi palo na pamet. Mada, ovu tehniku nisam video jos ni na jednom sajtu. Pretpostavljam da svi stavljaju klasicno tri razlicite slicice za tri razlicite liste jer se radi o svega par KB sve ukupno, tako da nije ni strasno ako se prave 3 HTTP requesta.

    A i jos smatram da ljudi kad prave sajtove, imaju u glavi mnogo drugih vecih stvari od ove, i kad sve to lepo zavrse, mrzi ih da se zezaju i sa ovakvom optimizacijom ciji se efekat, generalno, ne moze osetiti u praksi. Ne znam, mozda gresim.

    P.S. Da bi tutorial bio 100% tacan, u ovom prvom delu si slicicu nazvao arrow.jpg, a u CSS-u prikazujes arrows.jpg. Mogao bi to da prepravis.

    Jos jednom, svaka cast za zapazanje.

  2. Tačno je da se radi o par KB i u ovom slučaju kombinovana sličica je slične veličine kao sve tri zajedno, ali problem nije u težini sličice, već i dodatnom vremenu – DNS Lookup + Connecting + Queuing + Waiting for response.

    Ukoliko imaš Firebug, na Net tabu možeš videti detaljna vremena. Isprobaj sam, na onom mom primeru ostvaruje se ušteda oko ~0.1 sec.

    Za manje sajtove je skroz nebitno da li će biti 5 ili 10 zahteva, ali za veće sajtove smanjenje sa 50 zahteva na ~20 je veoma bitna opzimizacija. Trebaš imati na umu da se ne mogu svi zahtevi izvršiti paralelno…

    Pozdrav!

  3. @Milan: ako se ne varam, slicnu foru koristi,npr, Google http://www.google.com/images/nav_logo7.png
    slicica od nekih 5,2KB 🙂

    @salebab: hvala za Yahoo-ove savete 🙂

    dobar clanak