A good friend introduced me to the concept base64 encoding and I have gone down the road to research what scenarios it is best suited for.
On that road I found a great post by David Calhoun testing byte sizes by comparing binary images to their base64 counterparts. After reading it I thought it would be interesting to extend his UI icon test one step further and include an image sprite to see how that compares in byte size.
Note: I understand the drawbacks David has mentioned regarding sprites however I believe those drawbacks are manageable considering the potential gains to be had from a file size standpoint. Especially if you are managing more than just icons in your sprite files.
How I setup the test:
- Created a single sprite image from the 5 icons used in David’s initial test
- Created 4 test cases…
- image calls separated out for a total of 6 requests (1 CSS + 5 Images)
- 1 image call to a combined sprite image for a total of 2 requests (1 CSS + 1 Image)
- a file similar to split-binaries.css but instead use base64 for each image for a total of 1 request (1 CSS)
- a file similar to combined-binary.css but instead use base64 for the sprite image for a total of 1 request (1 CSS)
- Gzipped each CSS File and Image to get Gzipped byte sizes
- Minified each CSS File as I would on production
- Calculated total byte size from the combination of images + css needed for each case
So lets see how the numbers work out…
What I thought I would see:
- Test Case#2 (icon-sprite.png + combined-binary.css) would be the smallest in total filesize when compared to Test Case #1 (split-binaries.css plus its images) and Test Case #3 (split-b64.css)
- Test Case#4 (combined-b64.css – which replaces the image sprite with its base64 counterpart) would be the smallest total file size after Gzipping was done
- Gzipping Binary Images would sometimes lead to larger filesizes as those binaries would typically be compressed fairly well to begin with (or at least should be if you care about responsiveness)
- View on Google Docs
- assumption #1 turned out true. The creation of a sprite from the 5 icon images was smaller in file size than both separate images and separate base64 encodes.
- assumption #2 did not turn out to be true. However it was by such a small amount that you could pretty much say it is equal to Test Case #2 (we are talking about 23 bytes here)
- assumption #3 was interesting as gzipping of the binary spite resulted in a slightly larger filesize but gzipping the images individually ended up being smaller in total size. The differences are pretty tiny anyway and because of potential overhead in the gzip process this would probably not be needed if you are good about optimizing your source images.
So what does this really mean?
I think the numbers above depend on what you prefer to use and how you like to work. To be transparent I have always preferred image sprites. My opinion is managing them becomes easier the more you use them and there are a lot of good techniques today to get around some of their earlier drawbacks (such as using pseudo selectors to help get over clipping issues). So considering the findings above I personally would probably continue to stick with sprites.
However… you could possibly get benefit by making a sprite, converting to it base64 and then gziping it. The gain here would be 1 less request (and that could mean a lot on a larger site). To really test this idea I am going to build a case using a larger sprite file that has more than just icons in it to see how it scales.
In the future I am going to try to run performance testing to see baseline speed for each case from different locations (I’ll use webpagetest.org). Number of requests can sometimes make a huge difference in those tests so that might help put some additional clarity around this topic as well.
Further reading on base64: