Come aumentare le performance del mio sito? – CSS Sprites
![]()
Hai creato un sito, magari seguendo la nostra guida “Come creare un sito web dalla A alla Z”, ma noti che spesso i tempi di caricamento sono lunghissimi. I motivi alla base di questo comportamento possono essere molteplici, ma ci sono tanti piccoli accorgimenti da poter implementare per migliorare le performance. Oggi parleremo dei CSS Sprites.
Cosa sono gli sprites?
Durante lo sviluppo di un sito è normale utilizzare molte immagini di sfondo per realizzare vari effetti che non sono possibili utilizzando solo XHTML+CSS. Ad esempio possiamo usarle per realizzare dei titoli con un font particolare, oppure per dei bottoni per un menu. Per fare un esempio concreto, potremmo avere un menu a quattro voci, e realizzare le seguenti immagini:
![]()
E voler applicare queste immagini per lo stato hover, tramite CSS:
Sono richieste in totale 8 immagini, che si traducono in 8 richieste al server, una per immagine.
Uno sprite è la combinazione di più immagini in una, divisa in sezioni e manipolata tramite CSS. Seguendo l’esempio le immagini verrano combinate nella seguente:

Il concetto di sprite per il web è stato ripreso dai videogiochi anni ’80, in cui l’illusione di movimento era realizzata spostando un’immagine raffigurante i personaggi rispetto allo sfondo (nella foto il mitico Guybrush Threepwood di Monkey Island).
![]()
Oggi quasi tutti i siti ad alto traffico utilizzano questo tipo di immagini: questa ad esempio è quella utilizzata dai siti di Google:
![]()
Come migliorare un menu con immagini attraverso gli sprites?
Vediamo come realizzare il menu dell’esempio usando i due metodi, valutando poi le differenze di performance del sito. Iniziamo da un semplice markup XHTML, una lista di link:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" type="text/css" href="no_sprites.css" /> <title>Menu senza sprites</title> </head> </body> <ul id="nav"> <li class="home"><a href="#">Home</a></li> <li class="about"><a href="#">About</a></li> <li class="contacts"><a href="#">Contacts</a></li> <li class="portfolio"><a href="#">Portfolio</a></li> </ul> </body> </html>
Come puoi notare, ogni link ha una classe associata, per poter collegare il codice CSS. Applichiamo prima qualche formattazione di base, come la riduzione dei margini e alcuni accorgimenti per il testo:
body,h1,ol,ul,li,p{margin:0;padding:0;}
body{
background-color:#FFF;
color:#000;
font:75%/1.4 Helvetica,Verdana,Arial,sans-serif;
}
Ora rimuoviamo gli stili di default dalla lista non ordinata e allineiamo gli elementi applicando un float a sinistra:
...
#nav{
list-style:none;
margin:20px;
}
#nav li{
float:left;
margin:0 4px;
}
...
Guardando il risultato, ci accorgiamo di essere sulla buona strada: gli elementi sono allineati orizzontalmente e hanno un piccolo margine che li separa. Prima di procedere con l’applicazione delle immagini, dobbiamo avere una piccola accortenza di grande importanza, ovvero dare ai vari link la dimensione esatta dell’immagine che in questo caso è di 100px di larghezza per 27px di altezza:
#nav{
list-style:none;
margin:20px;
text-indent:-9999px; //questa regola nasconde il testo
}
#nav li a:link, #nav li a:visited{
display:block;
width:100px;
height:27px;
}
...
La direttiva display:block è molto importante, perché rende cliccabile tutta l’area del link e non solo il testo interessato. Ho inoltre nascosto il testo dei link, utilizzando la proprietà text-indent. Procediamo dunque con l’applicazione delle immagini:
...
.home a:link, .home a:visited {background-image: url(home.png);}
.about a:link, .about a:visited {background-image: url(about.png);}
.contacts a:link, .contacts a:visited {background-image: url(contacts.png);}
.portfolio a:link, .portfolio a:visited {background-image: url(portfolio.png);}
.home a:hover, .home a:focus {background-image: url(homeh.png);}
.about a:hover, .about a:focus {background-image: url(abouth.png);}
.contacts a:hover, .contacts a:focus {background-image: url(contactsh.png);}
.portfolio a:hover, .portfolio a:focus {background-image: url(portfolioh.png);}
...
Questo blocco di codice può spaventare, ma in realtà le regole sono molto semplici: ad ogni classe sono associate due immagini, una per gli stati “normale” e “visitato”, e una per gli stati “hover” e “focus” (quest’ultimo è attivato quando il link viene selezionato tramite il tasto TAB). Il risultato finale è perfettamente funzionante, ma possiamo migliorarlo attraverso gli sprites. Nota infatti come la prima volta che passi il cursore del mouse su un link c’è un piccolo ritardo nella transizione tra le due immagini: questo ritardo è dovuto al tempo di caricamento dell’immagine hover. Vediamo come eliminare questo fastidioso effetto indesiderato.
Come utilizzare gli sprites?
Per capire il funzionamento basta immaginare di guardare un poster su un muro attraverso un rettangolo ritagliato in un cartoncino: le parti circostanti il ritaglio ci impediscono di vedere il poster nella sua interezza, avendo quindi percezione di una parte limitata dell’immagine.
![]()
Come mostrato nell’immagine, attraverso CSS spostiamo l’immagine di sfondo, e l’aver impostato l’esatta dimensione per i link precedentemente ci garantisce che verrà visualizzata esattamente la porzione di immagine che ci interessa.
Un altro vantaggio degli sprites è che le modifiche al codice sono minime, interessando esclusivamente il CSS. La prima modifica è l’aggiunta della stessa immagine di sfondo per tutti i link del menu:
...
#nav li a:link, #nav li a:visited{
background-image: url(menu.png); //unica immagine per tutti i link
display:block;
height:27px;
width:100px;
}
...
Una volta fatto questo, dobbiamo posizionare lo sfondo inserendo le giuste coordinate per ogni elemento. Per conoscere queste coordinate possiamo aiutarci con un programma di fotoritocco qualsiasi, come GIMP o Photoshop. In questo caso è relativamente semplice, dato che gli elementi sono tutti della stessa dimensione. Vediamo come è strutturata una dichiarazione:
...
.about a:link, .about a:visited {background-position: -100px 0;}
...
Abbiamo utilizzato la regola background-position che prende come parametri lo spostamento orizzontale e quello verticale, in quest’ordine. Come abbiamo visto nell’immagine esplicativa, il pulsante “About” occupava la posizione a 100px dal bordo sinistro e a 0px da quello superiore. Dato che dobbiamo spostare l’immagine verso sinistra, il valore da inserire dovrà essere negativo. Facendo un po’ di conti si ricavano facilmente le posizioni di ogni elemento:
.home a:link, .home a:visited {background-position: 0 0;}
.about a:link, .about a:visited {background-position: -100px 0;}
.contacts a:link, .contacts a:visited {background-position: -200px 0;}
.portfolio a:link, .portfolio a:visited {background-position: -300px 0;}
.home a:hover, .home a:focus {background-position: 0 -28px;}
.about a:hover, .about a:focus {background-position: -100px -28px;}
.contacts a:hover, .contacts a:focus {background-position: -200px -28px;}
.portfolio a:hover, .portfolio a:focus {background-position: -300px -28px;}
E questo è il risultato finale.
Considerazioni finali
L’uso delle immagini sprite nello sviluppo di un sito web è un aspetto molto sottovalutato: a fronte di qualche ora impiegata per la creazione dell’immagine, si hanno vantaggi sia sotto l’aspetto di diminuzioni di richieste al server, sia come dimensioni dei file scaricati (infatti l’immagine totale è di dimensioni inferiori rispetto alla somma delle singole immagini). Effettuando dei test sull’esempio mostrato nell’articolo, si nota che nella versione con immagini multiple, il caricamento della pagina è distribuito nell’arco di circa 3.82 secondi, a causa del successivo caricamento delle immagini degli stati “hover”, mentre la versione con sprite impiega solo 0.521 secondi, scaricando tutti gli elementi della pagina.
Il guadagno totale è quindi circa del 50% (considerando il tempo di caricamento della pagina).
Bisogna però fare alcune considerazioni sul caso: credo che questa tecnica sia utile una volta stabilita una versione definitiva del sito, perché la creazione della sprite contenente tutti gli elementi di un sito è un’operazione abbastanza laboriosa.
Quindi la mia opinione è: immagini singole in fase di sviluppo e di testing, e sprites per la versione definitiva del layout. Tu cosa ne pensi?
30 commenti
Trackback e pingback
-
uberVU - social comments
Social comments and analytics for this post... This post was mentioned on Twitter by nando_p: RT @YIW Come aumentare le performance ... -
Twitter Bootstrap: come sviluppare rapidamente applicazioni web? | Your Inspiration Web
[...] cartella IMG ha al suo interno, invece, due sprites utilizzate per le icone dei pulsanti, dei menu, ecc. Le ... -
Come rendere trasparenti gli elementi con CSS3? | Your Inspiration Web
[...] di un’immagine. Questo effetto prima doveva essere creato utilizzando più immagini (magari utilizzando una sprite) ed era un incubo ...






quoto tutto l’articolo e ti faccio i miei complimenti ;)
Grazie @capobecchino :)
Io mi riprometto sempre di usare gli sprites in maniera più “massiccia”, ma per ora mi sono limitato ad usarli, nei miei lavori, solo per gli effetti di rollover.
Bell’articolo: chiaro ed esaustivo.
Ciao Francesco,
sapessi quante cose mi riprometto io! :D
Basterebbe solo un po’ di volontà al termine del progetto per la creazione dell’immagine e il calcolo delle varie coordinate e poi sarebbe tutto in discesa.
Ps
Grazie per i complimenti ;)
Grande articolo come sempre, reputo questo il miglior blog per webdev che tratta gli argomenti in maniera pratica ed intuitiva .. grandi
Ciao PIDE, e grazie per i complimenti. ;)
Tu hai mai utilizzato questa tecnica?
si principalmente per i rollover
Io li uso sempre più frequentemente, anche quando non è troppo compromessa la velcità… mi trovo bene.
Domanda: che progr. è quello che usi per monitorare il tutto? Io uso il plugin YSlow per FF ma alcune non mi piace e vorrei vedere cosa c’è in giro..
Ciao ricmanx,
lo screenshot è preso dall’ “ispeziona elemento” di Google Chrome. Di solito uso Firebug, però è esteticamente molto scarno.
YSlow lo uso anch’io: infatti volevo ampliare il discorso di ogni consiglio dell’estensione.
Inoltre potresti dare un’occhiata a Page Speed, che è sviluppato da Google, sempre come estensione di Firebug.
Penso che per comodità sia bene utilizzare più di uno sprite, uno per il menu, uno per le immagini strutturali del sito (logo, righe, simbolini, tratteggi, ecc) e poi uno per ogni modulo, così si risparmia nel numero di immagini ma anche gli interventi successivi restano agevoli…
Ottima idea, doc ;)
Modularità e compattezza!
Gran bel articolo! :-)
Mitico Guybrush!! :-D
Benvenuto iSimone e grazie ;)
Interessante davvero!
Articolo da 30 e lode :)
Ciao Francesco, grazie per i complimenti :)
È tutto merito di Guybrush che mi ha ispirato…il resto è venuto da sè :)
Just, devo assolutamente farti i complimenti doppi: sia per la qualità dell’articolo che hai realizzato che per avermi fatto ripiombare nei meandri dei miei ricordi con il mitico guybrush.
Grazie capo, è sempre un onore ricevere i complimenti da te.
Sono i secondi complimenti più grandi che abbia mai ricevuto (cit.) :D
non avevo ancora scoperto l’ispeziona elemento di chrome… veramente otttimo!!
come scritto nell’articolo anche io gli sprites sono una delle ultime cose che faccio, sennò si finisce per modificarli 100 volte ….
Ottimo articolo! In particolare la parte in cui si evidenziano i miglioramenti delle prestazioni con gli screenshot del software.
Alcuni di voi dicono che si promettono di usare i CSS sprites ma poi non lo fanno.
Sono d’accordo se il sito è già esistente, e modificare immagini, css e codice html richiederebbe veramente un durissimo lavoro.
Se invece il sito sta per nascere non c’è ragione per non ricorrere alla tecnica dei CSS Sprites. Lo dico soprattutto a quelli che la vedono la prima volta e credono sia una cosa complicata e accessibile solo ai professionisti… Non è così!
Per questa tecnica è richiesta una conoscenza di base dei CSS, per fare un esempio, basterebbe leggere i primi 2 capitoli del libro sui CSS di Gianluca Troiani, o comunque i primi capitoli di qualsiasi libro sui CSS.
chiaro e notevole!
come del resto tutti post del sito
complimenti ancora
:)
se posso, ho letto in fretta e non mi sembra sia stato già citato
ma specie per un newbe puo essere utile l’uso di spriteMe
lo si aggiunge ai preferiti e si sovrappone al sito, poi fa quasi tutto in automatico
:)
Grazie a Guybrush ora conosco una cosa in più sui css.. Quanto mi manca giocare a Monkey Island!
Premettendo che ho scelto la vostra guida a quella di html.it perche mooolto piu semplice e a mio avviso piu pulita,volevo chiedervi se mi aiutate ad aggiungere un semplice effetto di fade in fade out sullo stato hover con jquery sto impazzendo grazie mille
e una qualche guida per approfondire il jquery diciamo che un’infarinatura generale ce l’ho ma quando mi trovo di fronte aqueste sciocchezze non so come venirene fuori ecco perch evi chiedo umilmente aiutooo
grazie mille
allora nessuna buona anima che mi aiuta??
Ciao graficando,
innanzitutto grazie per i complimenti.
Per quanto riguarda il tuo problema, puoi descriverlo un po’ più dettagliatamente nel forum, così potremo dare un’occhiata insieme ;)
Alla prossima
…UNA SCIMMIA A TRE TESTE!!! =) Ho aperto l’articolo solo per l’immagine del titolo visto che la tecnica la conoscevo già ma è stato comunque un interessante ripasso. Tra l’altro la cosa del text-indent per nascondere il testo non la conoscevo, è utile per far indicizzare il sito dai motori di ricerca nonostante si usino delle voci del menù in cui anche le scritte sono parte del disegno giusto? Mettere invece font-size:0 non avrebbe portato allo stesso risultato?
Grazie!