Tuesday, June 23rd, 2009

Sprite Me! Helping you sprite up, but maybe you shouldn’t?

Category: CSS, Performance

There have been many tools to help make image spriting easier, by packaging up your images into one large image and splitting it up again via CSS.

Steve Souders just showed off a new little tool he created, Sprite Me at the Velocity conference that kicked off today. He has made it easier to work with sprites by:

  • finds background images: SpriteMe generates a list of all background images in the page. Hovering over the its URL displays the image.
    Each of the DOM elements that use that image are also listed. [DONE]
  • groups images: It’s hard to figure out which images can be sprited together, and how they should be laid out. For example, background images that repeat horizontally must fill the entire width of the sprite. Background images positioned left bottom must be at the right top of the sprite if their container might be bigger than the image. SpriteMe determines which images should be sprited together based on these constraints.[IN PROCESS]
  • creates sprites: SpriteMe generates the sprite for each grouping of images. This is done using open source tools, such as CSS Sprite Generator. [TBD]
  • updates CSS: The final tricky part of using sprites is changing the CSS. Sometimes the CSS is a rule in a stylesheet. Or it might be a rule in an inline style block. Or it might be specified in an element’s style attribute. Because SpriteMe runs inside your web page, it can find the CSS that needs to be updated. It makes the changes in realtime, so you can visually check to confirm the sprites look right.You can export the modified CSS to integrate back into your code. [TBD]

Great, a simple new bookmarklet to work with Sprites. It is always a good idea to sprite up right? Not exactly.

Vlad Vuki?evi?, a leader in the Mozilla community (and brought us cool stuff like Canvas 3D!) has spoken up on the internals of the browser, which shows you the trade-offs for the spriting approach:

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.

What alternatives are there? None right now…. but they are hopefully on the way. Some folks have been talking about the idea of packaging up images in zip files, and then the browser can manage more than just the download process, but also only load up what it needs:

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.

Rob Sayre, also of Mozilla, broached the subject:

Sprites have the advantage of working right now, but maybe there should be a way to serve up a multipart response with your sprite images as well. That would cut down on CSS rule count and maintenance, but still group the images in one HTTP request. Authors are already giving up the advantages of separate resources in return for speed, so maybe this is worth doing.

You can (in theory… haha) get some of these advantages with HTTP pipelining, but a multipart response would allow the server optimize the response order as they do with sprites today.

Posted by Dion Almaer at 12:01 am

4 rating from 28 votes


Comments feed TrackBack URI

Well, let’s not forget that making a 15000 pixel high sprite also makes the maintenance of the thing useless. This is once again a case of taking technology too far and leaving common sense out of the equation.

The dimensions problem is well known, and the spritegenerator by Project Fondue Sprite me is based on does take care of that:

Opera (at least as far as version 9.0) won’t recognise a background position greater than 2042px or smaller than -2042px using that boundary value instead. The tool takes care of this by creating new columns within the image output each time the vertical limit is reached.

We’ve been playing with base64 encoding and inlining images for content images but sprite solutions first and foremost also mean that you only put background images in there as they don’t need to be an img with alternative text.

A combination of CSS sprites with sensible dimensions, lazy-loading other images (for example with the YUI image loader) and inlining other data (either via base 64 or by serving the whole document as MSHTML as used in Outlook) seems to be the best solution.

Comment by ChrisHeilmann — June 23, 2009

As is the case with any technique – css-sprites also has limitations. Piling techniques/workarounds/hacks on top of each other won’t help the real problem – while imposing an intricate set of different limitations (that may again require additional workarounds).

From a performance point of view the current model of requesting an html page which in turn references a number of resources (javascripts, image content, stylesheets) – that again may point to further resources (stylesheets, images) – doesn’t make much sense. (But from a flexibility point of view it does)

We need servers to be smart about not just sending the recipe but also the ingredients on the fly in a multipart package.

Comment by rasmusfl0e — June 23, 2009

Or, you can just use GWT ImageBundle/ClientBundle which auto-bundles resources, efficiently packs them, with the compiler pruning any unused bits, and automatically rewriting the CSS, pruning, and minifying it, … :)

Comment by cromwellian — June 23, 2009

Wow…! Didn’t know that! Cool feature :)
All though tools like this are great in assisting people, I still think “Widgets” in general form are a “commodity problem” – as in should exist (mostly) within the framework itself, which means that for the widgets you use, this problem is (or should) already be *solved*. Though then there’s the rest of the website remaining, so it’s still a problem and maybe tools like this can help out, I however believe more in the “manual doing” here. I wrote a blog that explains them pretty easily though about 6 months ago here; http://ra-ajax.org/how-to-make-css-sprites.blog – for those interested … :)
Ohh yeah, I guess if you have needs for more then 2042×2042 big sprites and you can’t handle them in less then a handful of sprites non-the-less, then I am pretty certain that you’ve got other issues then Opera to worry about … ;)

Comment by ThomasHansen — June 24, 2009

Now I know why IE sucks up a gig of ram to display one page of our employee photo gallery. Who would have known that images need optimisation?

Comment by NickTulett — July 3, 2009

I think the solution is being “reasonable”. Apparently having large white area (especially when larger than content area) is not efficient and maybe even quite silly. I only use sprite for grouping icons of similar sizes and it not only saves loading time. but also become necessary in cases where webapps need to function in offline mode (while keep trying to connect the server), so that when I hover over an image button it only shifts it as oppose to trying to load a new image which will be empty or shown as the little square with red “x”.

Comment by coolnalu — July 7, 2009

Leave a comment

You must be logged in to post a comment.