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+

Sorry, comments disabled and hidden due to excessive spam. Working on restoring the existing comments...

Meanwhile, hit me up on twitter @stoyanstefanov