Coding Tips & Tricks


Home > MVC

MVC Data URI HTML Helper

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:

Image Tag

Instead, if you used Data URI's it would look something like this:

Image Tag Data URI

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.

CSS Data URI

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:

Html Helper

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.








Comments

Robin - 9/15/2011
I did a blog on the data uri schema a while back and came to the conclusion that it's kinda a interesting but ultimately useless; can't take advantage of CDNs, browser asset caching etc. http://robinosborne.co.uk/2011/01/18/data-uri-scheme

Dean Hume - 9/15/2011
@Robin - Yeah, very valid point. But I guess the great thing about Data URI's is that you don't need a CDN - the resources are embedded in the page - why not just gzip and cache the web page? This means only one resource to load...

Lex - 9/15/2011
Actually quite a big fan of this for the small graphics often used for bullets, forms and emoticons. It feels cleaner to me to limit it's use to CSS but it's definately a nice trick. btw the old 2 concurrent connections limit was per server not per domain, and now browsers by default allow more.

André - 11/10/2011
Very good article. Don´t you think about create a nuget extension with your code.

mahmoud - 11/10/2011
Great but I think sprite images are too better when all images are collected in one image which can be cached in client browsers too.

Arnaud - 11/13/2011
So you do save in terms of total number of transactions being made, but you make the transactions bigger. You also don't take advantages of multiple TCP connections to retrieve content in parallel, or HTTP pipelining if that's enabled. On a slow connection, this technique might even be detrimental.

kvdk - 12/10/2011
@Arnaud: By design http is best at downloading text data, so a html file can often be twice the size of binary data while still being equally fast Second, data URI's have a size limit (per uri, not total), therefor only work where it counts (images with ~50k pixels and below) so it does help


Add your comment

300 Characters left


Please fill this in to confirm that you are human