本文是作者调查Data URI在移动端性能表现的第三篇文章,第一二篇分别是:在移动平台上,Data URI要比原链接慢6倍;Data URI性能:不要在Base64上指责它。下面是笔者对原文的翻译。
大约一个月之前,我们做了一个研究,关于使用Data URI构建Web组件性能不佳的研究。在发表调查结果后,来自Web性能社区的一个最为持久的问题也随即显现出来:
怎样把Data URI和作为在页面上减少HTTP请求数的CSS Sprites进行比较?
这个问题是引人深思的,在如今的Web设计中,Data URI在Web设计上的一种典型应用方式就是替代Sprites,尽管这不是它的唯一用途:Data URI也可以被使用在其他资源上,如JavaScript。
在本文,我们将提供更多的背景知识来说明Data URI性能是一个非常重要的问题,一些实验细节以及Data URI或CSS Sprites在移动端有哪些更好地表现。
关于CSS Sprites
CSS Sprites是由CSS Zen Garden和Mobify用户体验副总裁Dave Shea在2004年引进的一项图像管理技术。CSS Sprites提供了一种非常巧妙的方式把多张图片合并成一张。利用CSS Sprites能很好地减少了网页的HTTP请求,从而大大的提高了页面的性能,这也是CSS Sprites最大的优点。
右图是一张图片,而通过下面的代码,你可以分别使用图中的三个部分。
#home{left:0px;width:46px;} #home{background:url('img_navsprites.gif') 0 0;} #prev{left:63px;width:43px;} #prev{background:url('img_navsprites.gif') -47px 0;} #next{left:129px;width:43px;} #next{background:url('img_navsprites.gif') -91px 0;}
运行结果(备注:该例子来自w3schools):http://www.w3schools.com/css/tryit.asp?filename=trycss_sprites_nav
关于Data URI
Data URI的官方名称叫Data URI Scheme,开发者可以使用它把图像的内容直接嵌入到网页里,减少HTTP 请求 (http request) 的次数,优化网页。(该部分内容摘自:Sjolzy'blog)
通常,把图像在网页上显示出来的标准方式是这样:
<img src="http://sjolzy.cn/images/A.png"/>
同样的效果,使用Data URI可以写成:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA 7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC" />
为什么要对Data URI性能进行研究?仅仅是因为细节吗?
不!事实证明,使用Data URI和另一种技术可以轻易低于100ms这个交互体验预算,用户体验大师Jakob Nielson对用户体验交互进行了预算,而100ms是用户是否感觉交互反应慢的界限。
在研究过程中,我们的团队发现Data URI在手机上的性能表现与桌面端并不匹配,之所以会导致性能差,主要是把实例化的JavaScript实体作为Data URI,而不是文本节点内部的脚本元素。
但没人能够解释Data URI的这种表现,为什么base64应该创建更多额外的负载。于是,我们开始调查这一问题是不是特定于JavaScript或者在使用Data URI的Web资源时,还存在一般的其它性能问题。
Data URI性能对Web设计师是非常重要的,它也是Web应用程序开发者最小化HTTP请求的最佳实践。Data URI通常被用在贯彻整个网站的较小图片上,但据我所知,目前还没有任何指导提供给设计师,告诉他们在一个页面里使用Data URI的size和资源数量上限。
从更广阔的背景来看,像Google Chrome团队、Apple Safari团队、Firefox团队、WebKit开发者以及微软的IE团队一直在致力于构建更快的浏览器,而对于Web开发者来说还远远不够。因此,开发人员了解不同的性能概况技术是非常重要的,这样他们才能正确的应用。
虽然浏览器给我们提供了一个抽象的环境,并且免费帮大家实现了许多细节,但仍然有许多浏览器行为需要开发者去了解,尤其当我们设计一个友好的移动网站时,在不到一秒的时间内就要将所有的内容渲染出来。
实验方法
为了回答以上问题,我们对它们第一次加载(没有缓存)所用时间以及一旦浏览器存在缓存,它们所表现出的性能差异有哪些都非常感兴趣,我们尽可能模拟非常真实的场景进行试验。我们选了互联网上最大的电子商务网站:Amazon.com的actual sprite来试验,该sprite将近25KB,并且包含39张独立的图片。
创建两个HTML块,并且放在iframe中进行加载。第一个iframe里包含CSS来指定sprite文件的位置和作为背景图片的每个独立sprite布局的偏移量;第二个iframe针对相同的图片内嵌了base64编码Data URI。Sprite condition iframe HTML、Data URI condition iframe HTML分别是两个iframe的测试链接。
在iframe被实例化之前,立即启动性能测量(当src=attribute被分配)以及当iframe加载事件被触发时再马上结束。由于iOS平台上没有导航计时API,时间分辨率对精确到毫秒的日期对象是有限制的,但考虑到性能的巨大落差,它足以应付此次的测试了。
这次试验主要测试了缓存和没有缓存条件下的Data URI和Sprite表现,总共有4个条件,每个条件都是在一个独立的iframe里执行。Data URI和CSS Sprites条件都是进行随机分配的,但是每个缓存测试条件都是在未缓存的测试完成后立即启动的。这是通过使用一个带有父窗口的单独iframe使缓存和没有缓存的条件保持一致。在所有的资源中包括所有条件下的iframe HTML内容以及CSS Sprites里都使用了cache-controlt头:
Cache-Control: public, max-age=2592000
共收集了280个样本进行了分析。
结果&总结
值得注意的是,CSS Sprites在没有缓存的所有浏览器上比Data URI明显快了几百毫秒,这尽管是事实,但不得不提的是,CSS Sprites实际上需要额外的链接并且还会带来所有相关的链接开销,包括TCP慢启动。
从结果中我们可以发现,缓存条件下,Android 4.2和iOS 6的CSS Sprites大概有2倍的性能提升,不同的是,iOS条件下减少了220ms,而Android 4.2在原生浏览器下减少了70ms。Chrome和Firefox在Android上要表现的好点,在CSS Sprites情况下有50%或60ms的性能差异。
记住,这仅仅是对一个25KB的Sprite所进行的测试,你可以看到在两种条件下显著的性能差异。一般来说,除了给每个单独的图像固定成本外,性能还是对Sprite图像尺寸收集的一个功能。如果你将大量的图片和脚本移到Data URI中,那么,对性能的影响将会更加显著。
基于这个研究,我建议开发者限制Data URI在较小资源上的使用,并且不要在CSS或内联HTML里多次使用。15-20KB已是Data URI的最大尺寸了。对于移动来说,不超过3-5个实例已是最好的经验法则了。
via:Mobify
3 楼 dohkoos 2014-04-08 23:13
2 楼 sp42 2013-09-26 13:19
1 楼 clxy 2013-09-26 09:31
但是Data URI还可以处理音频和视频。
CSS Sprites可以搞定Image,但是有Audio Sprites或Video Sprites搞定其他的吗?