Performance is a crucial factor when building websites. Whenever we load a web page, the browser sends a request to each and every file that is linked in the HTML and CSS files. Designers use CSS image sprites to reduce the number of requests to the server. Using data URIs is also another good alternative to reduce server requests.
Data URI represents a file type and it’s content in an text string which is encoded using the base64 encoding system. The beauty of this string is that you can directly store an image in the HTML or CSS file itself, rather than referring to the external source.
The general format of data URI is as follows:
1 | data:[][;base64], |
As an example an image encoded string looks like this:
1 | data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA6CAYAAADhu0ooAAAFP0lEQVR4nO2bX0gcRxzHP3uRNKJwAYuGCimREsFWaRNiFNp9qHnrEmmwpMlDaSCPDZFCHtqElpaaFgLlQktfmlAo1EYUQmQfqw/bghIsDTEVlNYQwaCCkAOPs0HZPvz2vDvd82Znd/2T9gOHujcz+/s6O7+Z+c1vDWLActxK4CjwOvAqcND7JIFqr9gSkAZmgIfAOPAbcNc2jadR22RE1ZDluEngbaALeBOo1GwqCwwDA8CAbRpLUdgXWqjluE3AJeA0+uJKkQV6gWu2aUyGaUhbqOW4LwFfIr24J4wRCqwiPXzFNo2/dBoILNRy3L1ID34C7NW5aQiWgB7g66DjOJBQy3EbgVuIg9lO7gKdtmnMqVZIqBa0HLcLGGP7RQK0AmOW4x5VraAk1HLcD4B+8lPDTq... |
PNG icon |
---|
data URI icon |
Data URI isn’t only limited to images however, you can use any file type including HTML itself inside a HTML document.
When we were developing the mobile and iPad websites we used high quality vector SVG images for the logo and the icons. The reason we did this is because when using regular images the result is blurry on the iPhone and on the iPad screens. To give a better experience we used SVG via data URI.
Drawbacks
There are few drawbacks to using data URIs.
-
Local caching
When we use images, a browser caches them locally separate from the HTML, but the media that is represented by a data URI cannot be cached separately.
-
Slow scanning
Since the encoded URI string is very lengthy, it’s hard to scan in the source code. Most of the the time the text editor will get stuck for a second or two before beginning searching. This also makes it more difficult for security software to scan content of the page. At Frontcube, we use Sublime Text 2 for development and we hit CMD+i all the time to search for keywords. When we were progressing with development we realized that Sublime was getting extremely slow during searching. Finally we separated all off the data URIs in to a separate SASS partial and assigned descriptive variable names. Then we included the partial to the main stylesheet. This helped us to keep the code clean as well as to boost the Sublime search.
-
Updating media
When we apply changes to the media elements, we must re-encode to use the new element. This problem can be easily remedied with SASS and Compass. I’ll show you how in the following section.
How to encode the files?
If you do a Google search you’ll be able to find plenty of tools that will convert your media files to data URIs. By far dataurl.net is the best and the simple tool we ever used.
Using PHP
PHP comes with a built in base64 encoding function called base64_encode
. If you want to convert media directly in a .php file you can create a function as follows.
1 2 3 4 5 6 | <!--?php <br ?--> function create_data_uri($source_file, $mime_type) { $encoded_string = base64_encode( file_get_contents($source_file) ); echo ('data:' . $mime_type . ';base64,' . $encoded_string); } ?> |
1 | <img src="<?php create_data_uri('logo.png’, ‘png’) ?>" alt="“Logo”" /> |
You can even use PHP inside your CSS file. If you’re interested in learning more about this, Chris Coyier has written a post on using PHP inside CSS.
Using Ruby and Rails
To use base64 inside Ruby and Rails you’ll need to require the ‘base64’ library. In Rails you can create a helper function as follows.
Then you can call the function as:
1 2 3 4 5 6 7 | require ‘base64’ def create_data_uri(source_file, mime_type) file_contents = File.open(source_file) { |f| f.read } encoded_string = Base64.encode64(file_contents) puts "data:#{mime_type};base64,#{encoded_string}" end |
1 | <img src="<%= create_data_uri('logo.gif', 'gif') %>;" alt="“Logo”" /> |
Using Compass and SASS
Compass provides a very useful helper function called: inline-image. You can directly call this function inside an SASS file if you’re using Compass.
1 2 3 | body { background: inline-image(“../images/logo.png”) } |
This solves a lot of problems when it comes to editing existing files. Since the function refers to the external source file, you can edit or replace the file as need. Compass will convert the media file on the fly when compass compiling codes to CSS.
Browser Compatibility
Almost all modern browsers support data URIs, but IE 9 doesn’t support them due to the security scanning issues I mentioned earlier. To get around this you can create a IE only stylesheet to satisfy IE or use a progressive enhancement approach.
During the Al Jazeera mobile site implementation, we had the same issue with some HTC mobile browsers. We overcame this with a progressive enhancement approach by providing fallback PNG images.
Performance
Data URIs are considered as the best method of minimizing HTTP requests. This practice is referred to as using ‘inline images’. Minimizing HTTP requests leads to high performance.
However a very recent research study claims that Data URIs are 6x slower than source linking, but still data URI is an interesting technique to learn. Isn’t it?
Question: Have you ever used data URIs in any of your projects? If so, share your interesting experiences with us. Please comment below and let’s discuss!