One of the new features introduced in IE8 is support for the data: protocol. Though IE8’s support this protocol is a welcome one, it is very limited in terms of features and usage compared to other browsers that have been supporting this protocol for quite a long some time. The data: URI scheme (or protocol, to use a familiar term) has been around for more than a decade but it was hardly used due to inconsistent browser support. Some web browsers have been supporting this protocol right from their V1, but the protocol capabilities and usage limitations inherent in them varied widely. However, recent versions of popular web browsers provide better consistency in data: protocol handling thus reducing the gap.
The purpose of data: protocol is to embed resources of any type, binary or text, within a page itself so that the browser doesn’t have to make network requests to remote servers and the saved bandwidth might be used to retrieve other resources in the page. Resources that are static or change infrequently (site logo, bullet images of lists, mini CSS style sheets/JavaScript code – to name a few) are the best bets to go with this protocol. I should emphasize that the resource file size be smaller and appearing in just few places in a page. Let’s see why towards the end or maybe you would figure it out by yourself as we go. The format of the data: protocol is:
data:MIME-Type;Parameters;Base64,Data Sequence
Everything except the URI scheme and the data sequence are optional.
MIME-Type can be any valid “type/sub-type” as specified in Content-Type HTTP header (but not all browsers support all MIME types for the data: protocol). If omitted it defaults to text/plain.
Parameters are an optional list of key=value pair, each separated by a semi-colon. If both MIME type and parameter list are omitted, they default to text/plain;charset=US-ASCII.
Base64, another optional parameter indicates that the data is base64 encoded (typically for binary data). Omitting this parameter would mean that the data is in URL-escaped format: URL unfriendly characters are specified in %xx (hex) format. Nevertheless, you can represent every byte in the data stream in hex format and it would just work fine.
As you aware, base64 encoding bloats the data size in a 3:4 ratio (every triplet results in a quartet after encoding), resulting in a bigger encoded size. With the URL escape method, the bloating ratio will vary positively because only non-URL compliant characters need to be escaped using the hex format. However, if every byte in the data stream is hex-escaped, it bloats the result in a 1:3 ratio – each byte results in three bytes. For example, if the original data size is 1024 bytes, the base64 encoding yields 1,366 bytes and a hex escaping would yield 3,072 bytes. So, using the data: based resources heavily, either the same resource being used in multiple places or too many unique resources in a page would just increase the HTTP payload bringing down the performance.
Since the data: protocol is nothing but an URI scheme, theoretically it can be used anywhere an URI is expected, but browsers vary in its usage contexts. Nonetheless, all browsers support data: resource anywhere an image URI is expected including CSS properties. Here are a few examples:
-
HTML
- <img
src=”data:image/jpg;base64, base64_encoded_jpg_data”
/>
- <iframe
src=”data:text/html, URL-escaped_or_hex-escaped_html”
/>
- <table
background=”data:image/gif, Hex-escaped_gif_data”
/>
- <body
background=”data:image/png;base64, base64_encoded_png_data”
/>
-
CSS
- .data_gif: {background-image: url
(‘data:image/gif;base64, base64_encoded_gif_data’)}
- .data_png: {list-style-image: url
(‘data:image/png, hex_escaped_png_data’)}
Will see some samples in the next entry but before then have your IE8 installed and any other browser that supports data: protocol already (FireFox, Safari 3+, Chrome or Opera).