Vladimir Vukićević — Words
 



To Sprite Or Not To Sprite

CSS Sprites have been around for a while, and keep coming up as a way to get blazing fast speed to your site.  Steve Souders just showed off SpriteMe! at Velocity ’09 (speaking of — why use the CSS Sprite Generator or other server-based tools when you can use <canvas> and toDataURL and generate sprites on the fly?).  However, there are a number of misconceptions about CSS Sprites, the main one being that they have no downsides.

The basic idea of CSS Sprites is to combine a number of images used on your site into a single image, thus reducing the number of HTTP requests that need to be made to your site.  The image is rendered using a CSS background and background-position (which, incidentally, means that your markup becomes more complex; the image to use is specified in CSS, not in a plain <img> tag).

The biggest problem with CSS sprites is memory usage.  Unless the sprite image is carefully constructed, you end up with incredible amounts of wasted space.  My favourite example is from WHIT TV’s web site, where this image is used as a sprite.  Note that this is a 1299×15,000 PNG.  It compresses quite well — the actual download size is around 26K — but browsers don’t render compressed image data.  When this image is downloaded and decompressed, it will use almost 75MB in memory (1299 * 15000 * 4).  If the image didn’t have any alpha transparency, this could be maybe optimized to 1299 * 15000 * 3, though often at the expense of rendering speed.  Even then, we’d be talking about 55MB.  The vast majority of this image is blank; there is nothing there, no useful content whatsoever.  Just loading the main WHIT page will cause your browser’s memory usage to go up by at least 75+MB, just due to that one image.

That’s not the right tradeoff to make for a website.

Another (but much less important) downside is that if a sprite-using page is zoomed using the full-page zoom feature that’s present in many browsers, the browser may need to do extra work to get the correct behaviour at the edges of these images — basically, to avoid adjacent images in the sprite from “leaking in.”  This isn’t a problem for small images, but can be a performance hit for bigger ones.

There are cases where CSS sprites are clearly beneficial; the main example is combining a bunch of small similarily-sized images into a single one.  For example, a bunch of 16×16 icons used as indicators for various things on your site, or a bunch of 32×32 icons used as category headers or similar.  But combining images with vastly different dimensions, especially when there are skinny and tall images in the same sprite as wide and short ones is almost never a good idea.

However, sprites do improve page load time (at least initial page load — on subsequent page loads, the browser hopefully has the images cached).  What’s the alternative?  Unfortunately, there isn’t one, yet.  Many browsers have support for offline manifests already; it might be possible to extend that to allow downloading one file (like a jar/zip file) that contains a manifest of resources and equivalent URLs that are contained inside it.  But any such work won’t show up on the web for some time yet.

So, when deciding whether to sprite or not to sprite, keep in mind that there are factors in play other than raw page load performance.  As a general rule of thumb, if most of your sprite doesn’t contain real image content, you should probably avoid using it.  Also, keep an eye out for future solutions that will preserve both the page load speed, as well as avoiding the negative memory and performance impact of sprites.


22 Comments to “To Sprite Or Not To Sprite”  

  1. 1 Tom B.

    There are some more cons for using sprites -

    - Sprites can make your markup complicated and a living hell to maintain, for example – you must use absolute sizes to elements with “sprited” icons, browser compatibility can become a real pain.
    - You want to change an icon? the size of a bg image? you need Photoshop. and someone who can use it…
    - If you use 32bit PNG files and still care about IE6 compatibility (damn customers and their demands..), you’ll need about 15% more time to work around all the quirks, add dummy html elements and a complicated position based CSS just for IE6.

    and there are more.

    I use sprites only for complicated bg images or similar icons with different color themes etc.
    For all the rest, I feel that the 10-20 http requests are a small price to pay for the readability and maintainability of my code.

  2. 2 Dariusz Siedlecki

    Hey Vlad, you mentioned that many browsers support offline manifests. Do you have any link to a test page, or just a simple explanation on how they treat it and which browsers are we talking about?

  3. 3 RichB

    The main problem with CSS Sprites (forgotten by most people, including Yahoo.com) is that background images don’t get printed by browsers. So you need a separate @media print {} section in your stylesheet to fix things up again, or simply to go back to boring tags.

  4. 4 Mathias Bynens

    @Tom:

    - If you use 32bit PNG files and still care about IE6 compatibility (damn customers and their demands..), you’ll need about 15% more time to work around all the quirks, add dummy html elements and a complicated position based CSS just for IE6.

    How is that? I usually just re-open said PNG and save it as GIF. Then I simply override the background-image property for the applicable element in my “less than or equal to IE 6″ stylesheet. Sure, quality might be reduced a bit for those using IE6, but at least they won’t be getting the grey “look everyone, I’m IE6, I don’t support alpha-transparent PNGs” background. The site will still look good; just not as good as when viewed in a decent browser. Progressive tarnish, if you will.

  5. 5 Ramon Smits

    You ofcourse do not build the CSS itself. You generated it as also the large bitmap itself. Like putting all images in a certain folder into one “sprite.png” where you have an “sprite.dat” that contains a list of the files in the sprite and the x/y offsets in that sprite image.

    In code you then do: Is image X in sprite.dat then put that info into the css or else just reference the image directly.

  6. 6 Stifu

    I use spriting a lot, but when it makes sense to me.

    The main problem I have with CSS sprites is related to background-repeat issues. Sometimes it’s just not possible to do what you want with a single image due to too much of the image showing when you wouldn’t want that.

    An example of this: http://stifu.free.fr/dl/temp/ie-test.html (this was a test case showing a bug in the Dean Edward’s IE7 library)
    This is something I use on my site: draw a stylized blue line behind h1 titles.
    The blue background image behind titles is made of 2 images (one for the left and right sides, one for the middle background), although I wish I could have done it with just one in an elegant way. The only way to make it with just one image would be too add empty space in the image to make sure the parts don’t collide, and make the middle background part wider than necessary, but I didn’t really like the idea.

    I just wish I could repeat only a part of an image, that’d be powerful… Like, repeat-x only what’s between the 3rd and 4th pixel (horizontal) of an image, for example.

  7. 7 jmdesp

    This is a bit off-topic as it’s unusable for css sprite, but Firefox supports multi-part content, as a forgotten remnant of the multiple proprietary extensions of the first browser war.

    You can use that by sending back a multi-part mime, and each part will successively replace the preeceding one when it’s sent, you can use it to do some crude animation, or a waiting screen without using javascript, but not for css sprite.

  8. 8 Mike Shaver

    I wonder if any of the various texture-atlas generation techniques could be adapted to the sprite-making tools so that they would make better use of memory.

  9. 9 thedude

    Sorry, not buying it. That is a ridiculous example. it’s obviously a mistake or it was made by someone who doesn’t know sh*t about development. you can write an infinite loop in javascript but that doesn’t mean javascript is bad.

    and this: “Unless the sprite image is carefully constructed, you end up with incredible amounts of wasted space.” who is adding massive amounts of whitespace to their sprites (except this one idiot)?

    @TomB
    - you don’t need to use absolute sizes, learn css
    - don’t you need photoshop to create the images in the first place? or are you using clipart
    - solution: don’t use 24-bit pngs for sprites, no one said you have to

  10. 10 stef

    “- don’t you need photoshop to create the images in the first place? or are you using clipart”

    true. however, im frequently in a situation where the designer / photoshop guy has already gone home, developers dont have photoshop on their systems and we’re unable to make the smallest of changes to the design if sprites are used in the css that needs to be altered.

    when freelancing at home this isnt an issue (although i do struggle with PS), but if you’re part of a large team this can be a pain.

    of course this doesnt mean sprites are bad, but i do see where TomB is coming from

  1. 1 Rob Sayre’s Mozilla Blog » Blog Archive » Sprites
  2. 2 Mozilla Webdev » Blog Archive » Use Sprites Wisely
  3. 3 Ajaxian » Sprite Me! Helping you sprite up, but maybe you shouldn’t?
  4. 4 An overlooked problem of CSS sprites is … « Paul M. Watson
  5. 5 To Sprite Or Not To Sprite | dv8-designs
  6. 6 Point trop n’en faut — Performance web
  7. 7 To Sprite Or Not To Sprite at Vladimir Vukićević « Netcrema - creme de la social news via digg + delicious + stumpleupon + reddit
  8. 8 The Ashes » Blog Archive » Sprite Me! Helping you sprite up, but maybe you shouldn’t?
  9. 9 Having fun with Canvas, but the aim is to have to use it less and less; Performance wars move from raw JS to DOM on Dion Almaer's Blog
  10. 10 @font-face Hacks | Robert Accettura’s Fun With Wordage
  11. 11 Amazing with CSS Sprites List | AEXT.NET
  12. 12 A faster web with Resource Packages – Mozilla suggestion to have just one HTTP request - Robert's talk