CSS Sprite
Szerző: admin | CSS | 2011 július 6. 10:08

Css sprite

Ha webdesigner vagy, és a sprite szó hallatán a képen látható üdítőital jut először eszedbe, akkor ez a cikk neked szól! Legjobb oldalad is csak egy csiszolatlan gyémánt egészen addig, amíg ilyen apróságokkal ki nem emeled a szürke átlagból.

Egy régebbi cikkemben ugyan súroltuk a témát (Ma reggel megint arra keltem, hogy a takarítónő az őrület határát súrolja…), mégis úgy érzem, hogy ennek a hosszabb lélegzetvételű történetnek egyszer még valaki nagy hasznát fogja venni.

Dióhéjban

A css sprite nem más, mint az oldalon található különböző képek egybe olvasztása. Ilyen sprite a jobb oldalon lévő három közösségi oldal képe. Amint látható, nem korlátoz semmiben a tény, hogy egy képen van mindhárom ikon, így is tudom őket külön-külön mozgatni.

A fenti kép egy CSS sprite működését szemlélteti. Úgy kell elképzelni, mintha egy tetszőleges méretű ablakon keresztül nézünk a képre. Ez az ablak általában egy inline elem, mint amilyen a span is. Fixen elhelyezzük az oldalunkon valahol, majd a hátteret annak függvényében mozgatjuk mögötte, hogy melyik képet szeretnénk látni.

A nagy oldalak szinte kivétel nélkül használják őket, pl. egy Facebook sprite így néz ki:

Miért jobb mint az üdítő?

Például azért, mert léptékekkel segíthet csökkenteni az oldal válaszidejét, és a teljes tartalom betöltődését. Ezzel szemben a Sprite mint ital, csak pillanatnyi örömet okoz, ahogy azt a betiltott Sprite reklám is mutatja :)

A legtöbb weboldalon az idő 5-20 százaléka a HTML generálásával telik, a maradékot a képek, js és css fájlok betöltése viszi el, logikus tehát, hogy a spórolást ezeken kell elkezdeni. Mindhárom esetben lehetőségünk van tömörítésre, de csak egy bizonyos mértékig. Ez után jön képbe a HTTP kérések csökkentés, azaz az oldal ne 50-szer forduljon a szerverhez a fájlok lekérése miatt, hanem elsőre húzza le egyben az egészet.

Lássunk egy példát!

Legjobban egy ellőtte/utána állapot szemléltetheti a módszer ütőképességét, amelyre készítettem is egy példát.

Ilyen kevés képnél is jól látható, hogy mind időben, mind pedig méretben tudunk spórolni.

Idő

A böngésző kevesebbszer fordul a szerverhez, ez gyorsít a legtöbbet a műveleten. Gondoljunk csak bele, ha 8-szor kellene lemenni a boltba zsemléért. Vagy ha az egyik asztalról a másikra rakunk 20-at, ott se mindegy, hogy egyesével tesszük ezt, vagy kosárban egyszerre.

Azonban van itt még más is! Amikor a DOM szerkezete megváltozik (új HTTP kérés, egy elem hozzáadása javascripttel), akkor a böngésző motorja újrarajzolja a képernyőt. Ez mindössze 1-2ms, de 100 képnél már van jelentősége. Ráadásul ti is láthatjátok, hogy a második esetben azoknak a képeknek a lekérése, amelyek alapból nem látszanak, csak a megjelenítés pillanatában történik meg, ezért van az a villogó effektus.

Méret

Hogy lehet, hogy a darabolt képek együttes mérete több, mint a sprite-é? Úgy, hogy minden képnek van egy fejléce, ahol a használt színeket tárolja, a fájl nevét és hasonló paramétereket. Minden egyes kép esetében ez annyi, mint a nagy sprite-nál. Az előbbi példánál maradva ez olyan, mintha minden alkalommal amikor boltba mész, a boltos adna egy zacskót, plusz egy blokkot a zsemléről. A századik alkalommal valószínűleg már ráfizetés lenne neki a zacskók árán, illetve a blokkokon is, hisz ha egyszerre vittél volna mindent, elég lett volna 10 zacskó, 1 blokk.

Ki fog ezzel bíbelődni…

- Én biztos nem! – mondta egyszer egy programozó, és létrehozta a Spriteme nevű oldalt, ami elvégzi a munkát helyettünk.

Használatához mindössze annyira van szükség, hogy az oldalukon lévő SpriteMe linket felhúzzuk a könyvjelzők közé, majd a kívánt oldalra navigálva rákattintsunk. Egy doboz fog felnyílni, amely tartalmazza az oldalon található összes képet. A felső doboz azokat, amelyek a program szerint hatékonyan összeolvaszthatóak egy képbe, az alsó pedig azokat, amelyek nem. Ezen persze módosíthatunk, de ennél optimálisabb konfigurációnk nem lesz (feltéve, hogy minden képet bele akarunk tenni). Végül a Make Sprite gombra kattintva legenerálódik nekünk a sprite, és a hozzá tartozó CSS kód is.

Mikor álljak neki?

Véleményem szerint az oldalak fejlesztése közben egy dologra érdemes figyelni: ha vannak hasonló méretű képek, akkor azokat ne random vágjuk ki, hanem próbáljunk minél inkább egy méret felé orientálódni, így később kevesebb üres hely marad a sprite-on a képek közt.

Egyébként a fejlesztés befejezéséig nem érdemes ezzel foglalkozni. Ha már minden megvan, nézzük meg az oldal sebességét, alakítsuk sprite formátumba a képeket, majd elégedetten nézzük ahogy oldalunk villámgyors lesz.

Zárszó

Az oldalak optimalizálása a kedvenceim közé tartozik, mert minden egyes lefaragott ezredmásodperc győzelemnek számít. Ha a cikk olvasása után kipróbáltad, és hasznosnak találtad, írd meg egy hozzászólásban!

A világon minden 5-ik percben elütnek egy embert… szegény ember..

  • Áron Esztergomi

    Hasznos cikk:)

    Amúgy a base64 string rol mit gondolsz? az lehet még egyszerűbb, meg gyorsabb is.

    • http://67developer.hu/ Gergő 67

      Jó felvetés, egyszer már kellett használnom base64 kódolást, akkor azért mert a szerver aki szinkronizálta az adatait velünk, így küldte át a képeket szöveges formában.
      Utánaolvastam kicsit, és a következőket találtam:
      - Annyi HTTP kérés lesz, ahány képed van, tehát ebben a sprite elvileg jobb
      - Nem lehet cachelni a képeket (állítólag, ezt majd kipróbálom)
      - Méretre azt írják kisebb mint a neki megfelelő kép, ebben tehát jobb
      - CSS-ben sajnos nem lehet használni
      - A szervert szerintem jobban terheli a képek beolvasása fopen-nel, átalakítása és kiíratása, mint amennyit nyerünk kliens oldalon vele. Tény, hogy az oldalt a kliensek felé kell optimalizálni főleg, de ha például a szerver processzorának ehhez többet kell dolgoznia, akkor egy nagy forgalmú oldalnál szerintem jobban kell mérlegelni.

      Összességében én azt mondom, hogy ha ezeket kipróbálom és tényleg minden így igaz, akkor a base64 pl. ajax hívásokkor visszaadott képek megjelenítésére, vagy szerverek közti adatcserére, esetleg adatbázisban való képtárolásra lehet jó. Ha viszont lehet cachelni, akkor kisebb oldalaknál a statikus képeket, amik nem férnek valamiért optimálisan rá a sprite-ra, mindenképpen ezzel lehet érdemes kiszolgálni (ha nem háttérképek, mert ugye css-ben nem jó).

      Köszi a hozzászólást, érdemes volt utána járni!

      • Áron Esztergomi

        Részletes a válaszod:)

        CSS ben lehet használni a base64-et ez tuti, most próbáltam ki. Igazából pont ezért kérdeztem, mert ennek csak így lenne értelme.

        http://www.greywyvern.com/code/php/binary2base64

        Arra gondoltam hogy a CSS-el együtt be is jönne az összes kis kép (amelyek a layout részeit képzik), így tehát még a sprite request jét is meg lehetne spórolni, pláne hogy elvileg így a kép még kisebb helyet is foglal, sőt a sprite sok helyen nem is alkalmazható (pl ha egy 500×500 as div bal felső sarkába bg nek egy 10×10 es ikont akarsz betenni ami nem ismétlődik). A hátránya az egésznek szerintem annyi hogy a CSS kódot átláthatatlanná teszi, bár ha jól tudom CSS 3 ban lehet deklarálni elég sok mindent, amit majd később alkalmazhatunk az egyes elemeknél, így tehát akár egy külön css fájlban lehetne tárolni az összes képet.

        Nem csináltam még, azért is vetettem fel, hogy megtudjam a véleményed. Érdemes lenne számításokat készíteni róla.

  • Áron Esztergomi

    Hasznos cikk:)

    Amúgy a base64 string rol mit gondolsz? az lehet még egyszerűbb, meg gyorsabb is.

    • http://67developer.hu/ Gergő 67

      Jó felvetés, egyszer már kellett használnom base64 kódolást, akkor azért mert a szerver aki szinkronizálta az adatait velünk, így küldte át a képeket szöveges formában.
      Utánaolvastam kicsit, és a következőket találtam:
      - Annyi HTTP kérés lesz, ahány képed van, tehát ebben a sprite elvileg jobb
      - Nem lehet cachelni a képeket (állítólag, ezt majd kipróbálom)
      - Méretre azt írják kisebb mint a neki megfelelő kép, ebben tehát jobb
      - CSS-ben sajnos nem lehet használni
      - A szervert szerintem jobban terheli a képek beolvasása fopen-nel, átalakítása és kiíratása, mint amennyit nyerünk kliens oldalon vele. Tény, hogy az oldalt a kliensek felé kell optimalizálni főleg, de ha például a szerver processzorának ehhez többet kell dolgoznia, akkor egy nagy forgalmú oldalnál szerintem jobban kell mérlegelni.

      Összességében én azt mondom, hogy ha ezeket kipróbálom és tényleg minden így igaz, akkor a base64 pl. ajax hívásokkor visszaadott képek megjelenítésére, vagy szerverek közti adatcserére, esetleg adatbázisban való képtárolásra lehet jó. Ha viszont lehet cachelni, akkor kisebb oldalaknál a statikus képeket, amik nem férnek valamiért optimálisan rá a sprite-ra, mindenképpen ezzel lehet érdemes kiszolgálni (ha nem háttérképek, mert ugye css-ben nem jó).

      Köszi a hozzászólást, érdemes volt utána járni!

      • Áron Esztergomi

        Részletes a válaszod:)

        CSS ben lehet használni a base64-et ez tuti, most próbáltam ki. Igazából pont ezért kérdeztem, mert ennek csak így lenne értelme.

        http://www.greywyvern.com/code/php/binary2base64

        Arra gondoltam hogy a CSS-el együtt be is jönne az összes kis kép (amelyek a layout részeit képzik), így tehát még a sprite request jét is meg lehetne spórolni, pláne hogy elvileg így a kép még kisebb helyet is foglal, sőt a sprite sok helyen nem is alkalmazható (pl ha egy 500×500 as div bal felső sarkába bg nek egy 10×10 es ikont akarsz betenni ami nem ismétlődik). A hátránya az egésznek szerintem annyi hogy a CSS kódot átláthatatlanná teszi, bár ha jól tudom CSS 3 ban lehet deklarálni elég sok mindent, amit majd később alkalmazhatunk az egyes elemeknél, így tehát akár egy külön css fájlban lehetne tárolni az összes képet.

        Nem csináltam még, azért is vetettem fel, hogy megtudjam a véleményed. Érdemes lenne számításokat készíteni róla.