Data URI&MHTML: 用还是不用?

YAHOO!的性能专家Stoyan Stefanov先后发布了

NCZ也有

引起了我们对data uri的关注,国内的也有一些不错的文章,比如:

工作太过饱和一直未深究,而前不久YDN的Performance on Yahoo! Search for Earth Day再次提到,更是撩起了我内心沉睡的欲望…

data URI的优缺点

data uri的主要优点是减少了http请求数,Best Practices for Speeding Up Your Web Site

Inline images use the data: URL scheme to embed the image data in the actual page. This can increase the size of your HTML document. Combining inline images into your (cached) stylesheets is a way to reduce HTTP requests and avoid increasing the size of your pages. Inline images are not yet supported across all major browsers.

还有就是调用起来比css sprite更加灵活,缺点是增加了客户端的资源消耗。

浏览器支持情况

Data URIs explained

Most modern browsers support data URIs:

  • Firefox 2+
  • Opera 7.2+ – data URIs must not be longer than 4100 characters
  • Chrome (all versions)
  • Safari (all versions)
  • Internet Explorer 8+ – data URIs must be smaller than 32k

不能太迷信权威,NET.2971 – The RFC 2397 data URL – Part 1这里说的比较靠谱:

2.3 – Maximum size

The size of data URIs is limited in some browsers. IE8 for example has a limit of 32,768 characters [4].

Filename Size[px] Size[kB] Size[chars]
Wallpaper16001200.jpg 1600×1200 309 699052 – 9199 =

A test was done with IE 8 (8.0.6001.18702), Firefox 3.5.3 and Opera 10.0. A large wallpaper, 1600×1200 px, 309 kB was converted to Base64, resulting in almost 690k characters. This inline image was added to a HTML page and opened in the browser.

IE8 only displays the first part of the image (probably 32,768 characters), Firefox and Opera are showing the complete image.

When searching for information about maximum data size, Opera is often mentioned with a limit of 4100 characters, but this is apparently for older versions.

It is often said that inline images should be limited to small images, for example icons. In practice, however, often much larger images are used. Examples are the Google news pages with 80×80 px standard images (about 3000 characters), some pages contain more than 20 of them. We also see that all modern browsers support large data URLs which is a deviation from earlier policies.

MSDN上的data Protocol

Data URIs cannot be larger than 32,768 characters.

还有段视频Internet Explorer 8 Data URI(不想装淫光的下面有下载链接)

可以简单理解为我们只要把data URI的字符数控制在32768字符内就可以照顾到所有A级浏览器了。

IE6&7使用MHTML并注意MHTML在ie7/vista bug 解决方案就好了,JavaScript组件打包模式里说的比较明确:

MHTML在ie7+/vista缺少结束分割符无法显示,win03sp2缺少Content-Type会有安全提示,原因都MIME不标准,不是所有的东西都可以省。

下面要开始测试了,demo在此,是在WIN7 IE8的IE7模式进行的测试,结合httpwatchfiddler,虽然不是测试所有浏览器但可以反映出一些共同的问题。

PS:demo是在tommyfan的基础上改的,节省了我不少时间,感谢囯+先;99css所在的服务器大猫给开了gzip,有兴趣的朋友可以到 http://miao.in去看看:)

下载速度对比

正常网速

可见,base64稍慢

fiddler模拟低速

base64慢了不少

渲染时间对比

几毫秒可以忽略,不过还是base64偏慢,data:URI + mhtml troubles and solutions中有云:

data:URI takes much more time to be processed (in comparison to CSS Sprites or raw images) – about 10x more (for Firefox, for IE – 2x, for Opera/WebKit almost the same time). So in case of large images’ square (starting from 400×400, or 100k square dots), so you must be careful ibefore you completely convert all graphics to base64.

感官体验

并不是下载速度越快越好,还要考虑访问者的主观感受,比如逐步呈现(Progressiv Rencering),将css放顶部的原因就在于此,测试demo,虽然放底部速度更快,但放顶部可以逐步呈现,详见《High Performance Web Sites: Essential Knowledge for Front-End Engineers》(中译名:《高性能网站建设指南》)第五章的分析。

sprite的demo中页面是逐步呈现的,而base64在css下载完成前一直处于“白屏”状态

Data URIs for CSS Images: More Tests, More Questions走了点弯路,想把data uri的css放底部,可能他没看过《High Performance Web Sites》吧:) (Rob, this is only a joke~)

文件尺寸对比

原始的31个icon加起来16.5KB

sprite的css 1.4KB + 图片4.54KB = 5.94KB

data URI的css 51.2KB, gzip后16.5KB

对于大型站点来说流量 = ¥,这点sprite领先

CPU&内存对比

通过观察Windows任务管理器,base64比sprite多1%左右的CPU,多1M左右的内存

data URI使用建议

  • 能使用sprite的地方尽量使用sprite
  • 不方便使用sprite的时候才使用data uri,比如 - 宽高不固定且又又要求background-position:center bottom
  • repeat/repeat-x/repeat-y的图片
  • png-24图片,IE6用α滤镜时图片请求不到会导致浏览器一直处于卡死状态,详见Image Optimization, Part 5: AlphaImageLoader,用mhtml代替则可避免此问题(先下载css,再从缓存调用自身)

以上结果跟demo本身的特点有很大关系,希望能看到各位的更多测试结果

除了文中提到的文章,下面的也不错:

另外,我写了个生成器,改天详细介绍:)

———————- 2011-5-27 补充 —————————-

经秦歌兄提醒

“@ytzong: mhtml要慎用,通过切换css实现换肤时写在css中的mhtml图片调不到,要刷新页面才会出来” MHTML有0day漏洞,打系统补丁的IE6和IE7完全不支持 MHTML协议,不建议生产环境使用MHTML了 http://t.co/zFoFZTP

经某同事(安装有QQ电脑管家)反馈,其XP的IE7已不能显示MHTML,估计是管家帮其打了补丁。

MHTML还是不用的好,此功能也因此从CssGaga中去除