I have recently been looking into web page performance and one of the things I came across is the Data URI scheme. When you reference an image in your HTML, the client needs to go and retrieve the image. This creates an HTTP request and adds to the time it takes for the page to load.
What is the Data URI scheme? - well, it is a URI scheme that provides a way to include data in-line in web pages as if they were external resources. Instead of adding a reference to your image as a path or URL, you embed the image directly into the document using a Base64 encoded string. The browser automatically understands the string and decodes it there and then - instead of retrieving it via an HTTP request.
Normally you would retrieve the image like so:
Instead, if you used Data URI's it would look something like this:
By changing your code to the above example to use Data URI's, it means one less HTTP request. Imagine if you had a resource intensive page - if you updated your HTML to include the Data URI's that would cut down significantly on the HTTP requests and this would in turn speed up the load time! This means that we never need to request that image again!
This opens up a world of possibilities in terms of serving slower internet connections. If you are serving your site to Mobile browsers, this is an ideal way to speed up the load time. The code above can also be included in CSS.
Another advantage of using Data URI's is that web browsers are usually configured to make only a certain number (often two) of concurrent HTTP connections to a domain, so inline data frees up a download connection for other content.
Putting it all together
So, what's the catch I hear you say? Well, as with most new features the older browsers don't offer support. However, it's better than you think. FireFox, Chrome, Opera, Safari and IE8+ all offer support for Data URI's. Another factor to take into consideration is that every time you make a change to an image you need to update the Data URI. This could become quite a maintenance nightmare if your site was quite image intensive. This is where Asp.net MVC comes in.
Using the power of HTML helpers in MVC, I decided to put together a small project that would handle progressive enhancement and older browsers. In my MVC project, I created a new class and called it "ImageHelper". Then I added a method to check the browser version and determine if it is capable of handling Data URI's:
I then added another method that would convert the given image to a Base64 string.
In the above method, I am getting the path of the image on the server then reading it into a MemoryStream and converting the bytes to a Base64 string. After that it's all wrapped up in a method that creates the image tag for us.
Then you simply call it on your view like so:
You may wish to extend the above method to handle any further image attributes such as id, style, width, etc. Another way that this could be extended would be to add a layer of caching so that once the Base64 string has been converted, it simply needs to be retrieved from cache. I have previously written about caching in .Net.
I have noticed that the Base64 strings are quite large depending on the size of your image. Base64-encoded data URI's are 1/3 larger in size than their binary equivalent. However, this overhead is reduced to 2-3% if the HTTP server compresses the response using Gzip. I use the MVC Gzip Actionfilter as described on this page.
That's pretty much it! If you view the source on this page you will notice that quite a few of the images are using Data URI's. It's really easy to get up and running and it can add a significant improvement to your page load times. The project is available for download here, or if you would simply like to include the class in your project you can download it here.