Data URL给了我们一种很巧妙的将图片“嵌入”到HTML中的方法。跟传统的用img
标记将服务器上的图片引用到页面中的方式不一样,在Data URL协议中,图片被转换成base64编码的字符串形式,并存储在URL中,冠以mime-type。本文中,我将介绍如何巧妙的使用Data URL优化网站加载速度和执行效率。
1. Data URL基本原理
Data URL技术,图片数据以base64字符串格式嵌入到了页面中,与HTML成为一体,它的形式如下:
<img src="data:image/gif;base64,R0lGODlhMwAxAIAAAAAAAP///
yH5BAAAAAAALAAAAAAzADEAAAK8jI+pBr0PowytzotTtbm/DTqQ6C3hGX
ElcraA9jIr66ozVpM3nseUvYP1UEHF0FUUHkNJxhLZfEJNvol06tzwrgd
LbXsFZYmSMPnHLB+zNJFbq15+SOf50+6rG7lKOjwV1ibGdhHYRVYVJ9Wn
k2HWtLdIWMSH9lfyODZoZTb4xdnpxQSEF9oyOWIqp6gaI9pI1Qo7BijbF
ZkoaAtEeiiLeKn72xM7vMZofJy8zJys2UxsCT3kO229LH1tXAAAOw==">
几乎所有的现代浏览器都支持Data URL格式,包括火狐浏览器,谷歌浏览器,Safari浏览器,opera浏览器。IE8也支持,但有部分限制,IE9完全支持。
IE6/7是不支持Data URL技术。
2. 为什么Data URL是个好东西
Data URL能用在很多场合,跟传统的外部资源引用方式相比,它有如下独到的用处:
- 当访问外部资源很麻烦或受限时
- 当图片是在服务器端用程序动态生成,每个访问用户显示的都不同时。
- 当图片的体积太小,占用一个HTTP会话不是很值得时。
Data URL也有一些不适用的场合
- Base64编码的数据体积通常是原数据的体积4/3,也就是Data URL形式的图片会比二进制格式的图片体积大1/3。
- Data URL形式的图片不会被浏览器缓存,这意味着每次访问这样页面时都被下载一次。这是一个使用效率方面的问题——尤其当这个图片被整个网站大量使用的时候。
然而,Data URL这些不利的地方完全可以避免或转化。本文的重点就是要讨论这个问题。
3. 在CSS里使用Data URL
当第一次看到Data URL的作用和用法时,你也许会很不疑惑,“为什么要麻烦的将图片转换成base64编码字符串,还要嵌入的网页中,将HTML代码弄的混乱不堪,甚至还会有性能上的问题。”
诚然,无法否认缓存在浏览器性能中的重要作用——如何能将Data URL数据也放入浏览器缓存中呢?答案是:通过CSS样式文件。CSS中的url
操作符是用来指定网页元素的背景图片的,而浏览器并不在意URL里写的是什么——只要能通过它获取需要的数据。所以,我们就有了可以将Data URL形式的图片存储在CSS样式表中的可能。而所有浏览器都会积极的缓存CSS文件来提高页面加载效率。
假设我们的页面里有一个很小的div
元素,我们想用一种灰色的斜纹图案做它的背景,这种背景在当今的网站设计者中非常流行。传统的方法是制作一个3×3像素的图片,保存成GIF或PNG格式,然后在CSS的background-image
属性中引用它的地址。而Data URL则是一种更高效的替代方法,就像下面这样。
<style>
.striped_box {
width: 100px;
height: 100px;
background-image: url("data:image/gif;base64,R0lGODlhAwADAIAAAP///8zMzCH5BAAAAAAALAAAAAADAAMAAAIEBHIJBQA7");
border: 1px solid gray;
padding: 10px;
}
</style>
<div class="striped_box lazy ">
这是一个有条纹的方块
</div>
4.Data URL 问题
说到Data URI的优点,自然少不了“减少链接数”,把图片转为Base64编码,以减少图片的链接数。我们先想当然一下,同样一张图片,如果不用发起一个下载请求,打开速度是会更快的。但是,有几个问题需要关注下:
- 图片始终是要下载的,那么下载一张图片的速度快还是下载一堆编码快?
- 浏览器对图片的显示,处理效率哪个更快?
- 图片的缓存问题
5.DataURL在Web浏览器中的兼容性总结
- IE8+,Firefox,Chrome,Opera,Safari 等现代浏览器普遍支持data URL
- IE8 data URL 最大长度限制为32k字节,超出无效。IE9+没有这个限制
- IE只识别base64编码或百分号编码(URL编码, encodeURIComponent)的data URL,IE不识别无编码的data URL,非IE浏览器可识别无编码的data URL
- IE不支持对<iframe>,<frame>标签的src设置data URL
- IE官方说法说data URL仅支持以下5种使用场景:
- object (images only)
- img
- input type=image
- link
- CSS declarations that accept a URL
- 据本人实测,IE也在除了官方所述5种之外的其它场合支持data URL:
- a href
- meta refresh. 示例:
<meta http-equiv="refresh" content="5;URL=data:text/html;base64,xxxx....">
- script src
- window.open
- embed src
- 对于audio, video一类的元素,往往资源文件较大,使用data URL并不常见,我也没有对其进行测试。
- Firefox中粘贴截图是直接转换为data URL的图片,其它浏览器干脆无法粘贴,我记得以前Chrome好像可以粘贴截图的,今天再测Chrome,Opera都不能粘贴截图(<div contenteditable></div>做的测试). (粘贴截图常用于在线富文本编辑器)
- 可为data URL指定字符集编码。示例:data:text/plain;charset=US-ASCII,xxxx....
附录:
DataURL语法规则:
dataurl := "data:" [ mediatype ] [ ";base64" ] "," data
mediatype := [ type "/" subtype ] *( ";" parameter )
data := *urlchar
parameter := attribute "=" value