feedback
Jan 26 2010

Optimizing CSS with Base64 Embedded Images (with Bonus Utility!)

by John Dyer

 

As I design a new site (current site | early demo of new site), I am working through what combination of technologies (CDN, sprites, caching, gzipping, etc.) we want to use to optimize it. One tool I’m looking at is embedding images in CSS with base64 strings. Instead of the browser needing to make several calls, one for the CSS file and then one for each image, base64 embedding means that all of the images are embedded within the CSS file itself.

It’s great for small images or images that only show up on :hover or mouseover and you don't want there to be any delay in the image appearing. Here’s what it looks like:

Normal CSS

.myclass {
width: 45px;
background: transparent url(myimage.jpg) top left no-repeat;
}

CSS with Base64 Embedded Image

.myclass {
width: 45px;
background: transparent url(data:image/png;base64,LONG-STRING-OF-BASE64-TEXT) top left no-repeat;
}

Problems with Base64

  1. Works in all browsers except IE6 and IE7. Solution: use a conditional comments to give IE6/7 a stylesheet that still references the images.
  2. Base64 is bigger than real images: In my tests a base64 encoded string image is somewhere around 150% the size of a regular image. This means it’s unusable for large images.
  3. Hard to manage: If you change the image, you’ll need to reembed the base64 string. You also have to maitain a separate IE stylesheet.

How to manage it

To help figure out which images were worth embedded and help manage it, I developed a small utility that analyzes a CSS file and allows you to select which images you want to embed. You can also preselect them by adding a comment somewhere within your CSS declaration that says /*embed*/

What It Does

  • Finds all image URLs in your CSS file (note: no CSS3 multiples or borders)
  • Shows the size difference between the image and the base64 string
  • Shows the final size output size and the GZipped size for comparison to the original
  • Removes comments and whitespace if you want
  • Creates a new base64 stylesheet and a IE6/7 stylesheet with references to the original image

Download

Comments

Chris Korhonen January 26. 2010 11:46

Another tip - if you are using Ruby on Rails, take a look at the Jammit gem. It handles asset packaging at deploy time and can automatically convert images in a specific directory into base64 embedded images within your CSS (and MHTML files for IE6/7).

Very impressive and totally transparent to your workflow.
Chris Korhonen's last post: Flash, HTML5 & iPads

Chris Korhonen
LeRoy January 26. 2010 12:23

Thanks a bunch for making this tool available! I hadn't considered this form of optimization until now.

LeRoy
Sean Patterson January 26. 2010 12:45

Hey John,

I like the tool and the technology seems really interesting! To play "provocateur" a little, what additional benefits to the CSS images do you see outside of the first time page load? It seems to me that having the larger file size and maintenance issues of a massive text blob would be a major concern. Doesn't the browser already cache the images used after the first load? In addition, specifying a subdomain for your images (img.dts.edu) would increase the performance and make it easy to change layouts on the fly.

Looking forward to your thoughts
[:: Sean ::]
Sean Patterson's last post: Developer’s Toolkit: MMX Edition

Sean Patterson
John Dyer January 27. 2010 09:26

One of the biggest concerns today in web design is the user's experience the first time they hit a page. Subsequent caching is great, but you want that first experience to be solid. The number of different things the browser has to load plays a part in that experience.

On the design I'm working on, we have a dropdown menu that uses background images. Those background images don't normally load until a user mouses over the menu item. I would rather that the CSS file is a few KB bigger than have the user experience a delay downloading the images for each menu. There are other ways to accomplish this, so I build this tool to help decide if base64 is a good way to go for your current project.
John Dyer's last post: Purple CMS - Super Early Alpha (0.1)

John Dyer
Michael Lang January 26. 2010 13:36

An alternative would be to make an image sprite with all your images in it.  The first location that needs an image will load the entire sprite.  The other images shown on hover will already be downloaded and will appear instantly.

If no images are used until hover, then include a 1x1 transparent section on the sprite.  Use the 1x1 transparent image at the bottom of your page that is visible at load time...  That then preloads the entire sprite.

Michael Lang
John Dyer January 27. 2010 09:29

Yes, sprites are another good way to help manage images.

Of course sprites also trade-offs. For example, it's a lot of work  to manage a giant image with lots of little images inside and keep track of the background positions of each image. In addition, loading the same giant sprite into a browsers memory several times can cause browser memory usage to rise. I love sprites for certain things, but neither it nor base64 are one-size-fits-all solutions.
John Dyer's last post: Purple CMS - Super Early Alpha (0.1)

John Dyer
Sean Patterson January 27. 2010 11:41

[quuote]I love sprites for certain things, but neither it nor base64 are one-size-fits-all solutions.[/quote]

Precisely! So how is the base64 layout working for you currently? The demo site loads visibly faster than the original, and I'm thinking this could be really cool
Sean Patterson's last post: Developer’s Toolkit: MMX Edition

Sean Patterson
slipy January 29. 2010 11:54

Isn't better to use "normal" CSS everytime? With base64 is too many problems.
slipy's last post: Dámske plavky ako uliate

slipy
Al February 17. 2010 12:33

Two big thumbs up on your blog!

Al
duncan capicchiano February 19. 2010 08:28

Some wonderful insights there. Well done and maybe when I get time, I will come back and go through more of your blog.

duncan capicchiano
Fatcow Review February 24. 2010 09:27

I cannot seem to locate your syndication feed, I'd love to get more your posts.

Fatcow Review
Comments are closed
Web Statistics