data:urls – what are they and how to use them

April 10th, 2009. Tagged: images, performance

If you follow this blog you already know the infamous website performance rule #1 - reduce the number of HTTP requests. Actually, to celebrate Earth Day and to jump the "go-green" wagon/jargon, my favourite performance mantra as of late is "Reduce, Reuse, Recycle" (the Recycle part is a wee fuzzy but, oh well)

So to reduce the number of requests for JavaScript files, you combine all .js into one monolithic file.

Same for .css

For images - use CSS sprites to create one image files that contains all your little icons.

Yet another way to minimize the number of HTTP requests is to use data URLs (proper name is data URI scheme).

"data... uri? urgh-i? An example, please!"

Say you have this minuscule image:

which you include like:

<img src="http://phpied.com/images/check.png" />

This way you're actually using the http URI scheme.

Same thing using data URI will look like:

And the code for it:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC" />

This way the image in inlined in the HTML and there is no extra HTTP request to retrieve it.

data URI syntax

Let's take a look again at this img tag and its slightly disturbing syntax:

<img src="data:image/png;base64,iVBOR..." />

You have:

  • data - name of the scheme
  • image/png - content type
  • base64 - the type of encoding used to encode the data
  • iVBOR... - the encoded data
  • some , and ; and : sprinked for good measure

How do I base64-encode?

While there are some online tools that will let you upload an image or point to a URL, you can simply do it from PHP and the command line.

Say you have the filename check.png. Then go:

$ php -r "echo base64_encode(file_get_contents('check.png'));"

This will spit out encoded content for copy-pasting pleasure. Naturally you can also do this from your application code, if needed.

Using data URLs in CSS

If you want the same image as a repeating CSS background, you can use it like this:

<div id="data-uri-test"></div>
<style type="text/css">
#data-uri-test {
  width: 20px;
  height: 20px;
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC");
}
</style>

Where the gist of it really boils down to the same:

background-image: url("data:image/png;base64,iVBOR...");

Lights, camera... IE!

Everybody's favourite part of every technique... IE support. The thing is IE8 supports data URIs. Earlier IEs do not. But, there is a solution involving MHTML, which I'll describe in a follow-up post, since this one turn out kinda longish.

For the impatient and Russian-speaking among you - click here.

Tell your friends about this post: Facebook, Twitter, Google+

30 Responses

  1. [...] the previous post I described what data: URIs are and how they are useful to reduce the number of HTTP requests. Now, the problem with data: URIs is [...]

  2. [...] View original here:  data:urls – what are they and how to use them [...]

  3. The embedded images can’t be cached between different page loads in most cases, as the HTML is rarely cached. You also have to repeat the data of the image multiple times if the image appear in the HTML document multiple times. These are two big inconvenients, but still, the solution is interesting.

  4. Great article Stefan. Finished your book, OO JavaScript and am looking forward to your talk at JS Conf 2009.

  5. But if this image is in several places, like a logo in the header, wouldn’t it be counter productive? You save on http requests, but now the image will never be cached.

    Otherwise, I think this is a great in css files or for images that only appear once.

  6. @Joe – Thanks! Hope you liked oojs

    @anthony – that’s pretty easy to solve if you have one class name that contains the data: image and then you add the class to all elements that you want, e.g.

    .logobg {
    background: url(data:…)
    }

    <div class=”navigation logobg”>..
    helo, hello
    <div class=”footer logobg”>…

  7. It just happens that I’m reading the article on my E71′s native browser – no support for data:uri’s :( .

    I have no cyrillic on my mobile but anyway – Hristos Voskrese.

  8. [...] Data urls: putting the data inside the CSS (inline). [...]

  9. [...] recently I’ve been experimenting with data:url to inline background images into the CSS file. This reduces the number of files the browser has to [...]

  10. [...] Phpied.com – data:urls – what are they and how to use them [...]

  11. [...] discovered this method in this brilliant post where the same trick is used to for CSS and to reduce HTTP requests. And by reading that post I [...]

  12. Very useful article, Stefan :)

    One important thing about IE8:
    “Data URIs cannot be larger than 32,768 characters.”

    http://msdn.microsoft.com/en-us/library/cc848897%28VS.85%29.aspx

  13. Another thing I missed…
    When IE8 runs in IE7 regime it works like IE8 and Firefox or data:uri works as described in this article.
    Tested :)

  14. [...] been a fair amount written about data URIs recently: my colleague Stoyan Stefanov has written a couple of posts about data URIs, and my former colleague Hedger Wang also penned a post about how to use [...]

  15. [...] Msdn, http://msdn.microsoft.com/en-us/library/cc848897%28VS.85%29.aspx Stoyan, http://www.phpied.com/data-urls-what-are-they-and-how-to-use/, http://www.phpied.com/mhtml-when-you-need-data-uris-in-ie7-and-under/ R Reid, Detecting IE 8 [...]

  16. [...] 3. 图片素材文件的组织。首先是用好CSS Spirits的优势,回避它维护上的缺点。常犯的问题是,认为它好就把所有素材文件都放进一张图片中,不好维护,也无法重用。所以CSS Spirits的策略是对应CSS规划的,在核心级core.css中把所有定义基本风格的图片素材合并成一张png图,并做优化。不便整合的图(像平铺的虚线)可以用dataURI的方式做到CSS文件中。产品级CSS文件是会较频繁变动的,所以经常变化的素材图片不要放进spirits图中自讨苦吃。 [...]

  17. [...] 关于背景整合的问题,其实也提到了,是将整站背景完全整合在一起呢?还是如何整合呢?方案是还是按CSS规则进行,就是全部公用的整合在一张上,频道公用的整合,单独使用的整合。当然还有一些会被频繁更换的背景,这时候就得小了,也可以整合,这你就得考虑清楚,将他们放在整合的背景中的什么位置,便于你更换。克军还提到了关于背景图片的使用,使用dataURI的方式,这种方式听说不会产生http请求数,这个我还得找时间学习学习。 [...]

  18. Hi I have a problem in reading the base64 data using javascript which is store in xml

    This is exactly what I am trying i have a PHP code

    post.php : http://pastebin.com/WqnwphQq this returns one small xml which contents base64 data … which I am calling from AJAX post this is my java script index.html : http://pastebin.com/C0zppqsR

    the output of ele.firstChild.nodeValue is different in firefox and chrome

    I can see that the string which we get in firefox is totally change form the actual generated PHP response (I have checked it using firebug )… any pointers ??

  19. [...] the number of HTTP requests is a must, sprites are cool, but a pain to maintain, so there come data URIs (for all browsers) and MHTML (IE6 and 7). I've talked about these things on this blog to a point [...]

  20. [...] הרעיון של data-uri הוא שאת כל המידע הדרוש להצגת התמונה ניתן לשלב בכתובת, ולחסוך את הצורך באחסון של תמונה כקובץ חיצוני ובקריאת HTTP נוספת. הרעיון קונה לו תומכים ותופס תאוצה, וכלים נלווים מושקים חדשות לבקרים. [...]

  21. [...] data:urls – what are they and how to use them [...]

  22. [...] URIs (see this, this, and this) and Base64 encoding goes hand-in-hand. This method allows you to embed images [...]

  23. [...] http://www.phpied.com/data-urls-what-are-they-and-how-to-use/ ‹ 안녕하세요! Posted in 미분류 [...]

  24. [...] been a fair amount written about data URIs recently: my colleague Stoyan Stefanov has written a couple of posts about data URIs, and my former colleague Hedger Wang also penned a post about how to use [...]

  25. Spot on with this write-up, I honestly believe that this website needs a great deal more attention. I’ll probably be back again to see more, thanks for the information!|

  26. What’s Going down i am new to this, I stumbled upon this I have discovered It absolutely useful and it has helped me out loads. I hope to contribute & help other customers like its helped me. Good job.|

  27. Its like you read my mind! You appear to know so much about this, such as you wrote the book in it or something. I feel that you could do with some percent to drive the message home a little bit, but other than that, this is magnificent blog. A fantastic read. I will definitely be back.

  28. Hello my family member! I wish to say that this post is amazing, great written and include almost all vital infos. I would like to see extra posts like this .

  29. For anyone working with data URIs, http://datauri.net is useful for dealing with large sets of data URIs. It supports batch image encoding and automatic CSS generation which makes data URIs much more maintainable than other methods of managing data URIs (such as by hand).

  30. We are a gaggle of volunteers and starting a new scheme in our community.
    Your site offered us with helpful info to work on. You’ve
    done a formidable activity and our whole neighborhood might be thankful
    to you.

Leave a Reply