Home > Code Examples, General rambles > Base64 CSS Images for speed MSTASK

Base64 CSS Images for speed MSTASK


Hi all,

Following on from previous posts and the possible cheap ways to increase your web-site load times. I thought I’d share a little bit code that helps reduce the number of calls your web pages make when loading images either from CSS or in the HTML itself.

The process is straight forwards enough; It’s just a case of where you want to implement it, either during the build process or at runtime.

I personally like minify during the build process, combining and Base64 files before deploying and then caching. There are a number of solutions that will do all this for you at run time. (Seem comments on previous posts) The choice is yours.

For a recent project I used code similar to the following. There is a little gotcha you have to keep in mind when process to base64 encoding images and that is the limitation of older browsers.

Microsoft Internet Explore version 6 and 7 do not support base64 natively and IE8 has a size limitation of 32Kb. As with most issues around different browsers, building a simple browser sniffer to decide which to version of the CSS to send to the client and cache it, will help resolve the issue.

The downloadable version of the code is wrapped in an MSBUILD task, should you need to wire this up to your CI.

So the following image :

Light Box tools

Would be converted to the following inside the CSS file. Yes your files will get bigger but it’s still time saving and reduces the number of round trips, but I guess you knew that already else you would not be looking at this as an option.

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAK8AAAAy etc..

NB: WordPress does like to screw-up inline code, so see the download for a working example.

If you like it and feel the need, please donate and buy me a beer.


        public string ImagePath { get; set; }

private static string MakeImagesBase64(string stylesheet)
        {
            const RegexOptions MyRegexOptions = RegexOptions.None;
            const string RegexPattern = @"(?<=url\(/)(.*)(?=\))";

            var myRegex = new Regex(RegexPattern, MyRegexOptions);

            var result = myRegex.Replace(stylesheet, this.OnEvaluator).Replace(Environment.NewLine, string.Empty).Replace("/data", "data");
        }

private string OnEvaluator(Match match)
        {
            var uriData = LoadCssImage(this.ImagePath, match.ToString());
            return uriData;
        }

private static string LoadCSSImage(string capturedFilepath)
        {
            string imagePath = HttpContext.Current.Server.MapPath(capturedFilepath);
            int start = capturedFilepath.LastIndexOf('.') + 1;
            int end = capturedFilepath.Length;
            string imageType = capturedFilepath.Substring(start, end - start);
            string result = String.Empty;

            ////Try to load image, if we can't find it put back the original image path
            try
            {
                using(Image image = Image.FromFile(imagePath))
                {
                    System.Drawing.Imaging.ImageFormat format = image.RawFormat;
                    result = ImagetoBase64(image, format, imageType, capturedFilepath);
                }
            }
            catch
            {
                result = capturedFilepath;
            }
            return result;
        }

private static string ImagetoBase64(Image image, System.Drawing.Imaging.ImageFormat format, string imageType, string capturedFilepath)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                string result = String.Empty;
                image.Save(ms, format);
                byte[] imageBytes = ms.ToArray();

                string base64String = Convert.ToBase64String(imageBytes);
                var ie8ByteLimit = 32768;

                if (imageBytes.Length < ie8ByteLimit)
                {
                    result = String.Format("data:image/{0};base64,{1}", imageType, base64String);
                }
                else
                {
                    result = capturedFilepath;
                }

                return result;
            }
        }

  1. February 3, 2012 at 3:12 pm | #1

    Awesome!

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 324 other followers