图片的HTTP请求
请在主流浏览器中打开测试页面,在Fiddler里查看http请求。
1. 隐藏图片
<img src="1.jpg" style="display: none" />
测试:test_1.html
结论:只有Opera不产生请求。
注意:用visibility: hidden隐藏图片时,在Opera下也会产生请求。
2. 重复图片
<img src="1.jpg" /> <img src="1.jpg" />
测试:test_2.html
结论:所有浏览器都只产生一次请求。
3. 重复背景
<style type="text/css">
.test1 { background: url(1.jpg) }
.test2 { background: url(1.jpg) }
</style>
<div class="test1">test1</div>
<div class="test2">test2</div>
测试:test_3.html
结论:所有浏览器都只产生一次请求。
4. 不存在的元素的背景
<style type="text/css">
.test1 { background: url(1.jpg) }
.test2 { background: url(2.jpg) } /* 页面中没有class为test2的元素 */
</style>
<div class="test1">test1</div>
测试:test_4.html
结论:背景仅在应用的元素在页面中存在时,才会产生请求。这对CSS框架来说,很有意义。
5. 隐藏元素的背景
<style type="text/css">
.test1 { background: url(1.jpg); display: none; }
.test2 { background: url(2.jpg); visibility: hidden; }
</style>
<div class="test1">test1</div>
测试:test_5.html
结论:Opera和Firefox对于用display: none隐藏的元素背景,不会产生HTTP请求。仅当这些元素非display: none时,才会请求背景图片。
6. 多重背景
<style type="text/css">
.test1 { background: url(1.jpg); }
.test1 { background: url(2.jpg); }
</style>
<div class="test1">test1</div>
测试:test_6.html
结论:除了基于webkit渲染引擎的Safari和Chrome,其它浏览器只会请求一张背景图。
注意:webkit引擎浏览器对背景图都请求,是因为支持CSS3中的多背景图。
7. hover的背景加载
<style type="text/css">
a.test1 { background: url(1.jpg); }
a.test1:hover { background: url(2.jpg); }
</style>
<a href="#" class="test1">test1</a>
测试:test_7.html
结论:触发hover时,才会请求hover状态下的背景。这会造成闪烁,因此经常放在同一张背景图里通过翻转来实现。
注意:在图片no-cache的情况下,IE每次hover状态改变时,都会产生一次新请求。很糟糕。
2009-05-13晚补充:上面的解释有误,更详细的解释请参考续篇。翻转技巧指的是Sprite技术,例子:test_7b.html, 在ie6下不会产生闪烁。
8. JS里innerHTML中的图片
<script type="text/javascript">
var el = document.createElement('div');
el.innerHTML = '<img src="1.jpg" />';
//document.body.appendChild(el);
</script>
测试:test_8.html
结论:只有Opera不会马上请求图片。
注意:当添加到DOM树上时,Opera才会发送请求。
9. 图片预加载
最常用的是JS方案:
<script type="text/javascript">
new Image().src = '1.jpg';
new Image().src = '2.jpg';
</script>
在无JS支持的环境下,可以采用隐藏元素来预加载:
<img src="1.jpg" style="visibility: hidden; height: 0; width: 0" />
测试:test_9.html
终于到总结了
- 对于隐藏图片和隐藏元素的背景,Opera不会产生请求。
- 对于隐藏元素的背景,Firefox也不会产生请求。
- 对于尚未插入DOM树的img元素,Opera不会产生请求。
- 基于webkit引擎的Safari和Chrome,支持多背景图。
- 其它情景,所有主流浏览器保持一致。
对图片请求的处理上,个人觉得Opera走在前列。
番外
1. 用Fiddler监控Opera时,如果是本地服务器,需要在Opera的代理服务器设置里,将本地服务器勾选上。
2. 查看HTTP请求数,还有一个万无一失的方法是,直接查看Apache的access.log文件。
3. 我的Firefox对于重复图片和重复背景,会产生重复请求。禁用了所有扩展,问题依旧。有知详情者,还望告知。

May 12th, 2009 on 23:18
不请求隐藏图片或隐藏元素的背景也未必是个好事。页面中初始状态下隐藏元素一般留着有用的,当display属性的值变化,还是要再请求一次。这个问题,见仁见智。呵呵。
May 12th, 2009 on 23:19
不错 很好的参考
May 12th, 2009 on 23:25
“display: none”
貌似firefox也没请求…下午测试过…
May 12th, 2009 on 23:38
这里的实验结果及总结我不太确定其正确性。
这里(http://htstars.googlepages.com/HTStar.html )是我以前做的一个标星控件,通过控制背景图达到效果,在本机调试的时候很流畅,但是可能跟当时的网络和计算机性能有关,放到google pages上(网速较慢)则体验极差,经常性出现盲白,尤其是第4个不同icon的实例,尤其是IE(6),以至于我重写了一个通过控制图片的src的实现(http://htstars.googlepages.com/HTStar2.html ),虽然没有了盲白,但是在加载图片过程中的“停顿”体验也不佳。
p.s. 当然如果把两颗星合并成一张图片情况会较好。
请问这如何解释?
May 13th, 2009 on 0:11
今天还在群里讨论这个,玉伯真是总结得辛苦了。
May 13th, 2009 on 7:34
niubility~
顶哈~
May 13th, 2009 on 8:20
@Leo: 对隐藏图片和隐藏元素的背景,Opera不是再请求一次,是延迟请求。需要的时候才请求,我觉得更合情理。
@bigCat: 在firefox 3.0.10上,我这里能看到请求。
May 13th, 2009 on 9:11
先学习了。
May 13th, 2009 on 9:24
@雕叔: 又跑回去用fiddler和firebug测试了… 依旧没请求
但是去掉display:none后就有请求了
FF3.0.10
本地创建ooxx.htm
.foo {display:none;background: url(http://ooxx.me/logo.gif) }
<div class=foo>bar</div>
经测试safari chrome ie都有请求而firefox和opera没有
奇怪…
May 13th, 2009 on 9:24
太神奇了!这么好的文章!看完之后终于明白图片预加载是怎么回事了!
May 13th, 2009 on 9:44
很好的资料
May 13th, 2009 on 10:09
经常研究W3C的文档,才是做好前端设计的基础。博主算得上是UED的典范
May 13th, 2009 on 11:09
学习了
May 13th, 2009 on 12:04
如果是hover状态下,这里是否是特指IE6的hover BUG呢?“因此经常放在同一张背景图里通过翻转来实现。”其实,不大理解这句话,呵呵。
挺详尽的资料,给大伙是很好的沉淀,赞!
May 13th, 2009 on 12:23
以我的智商,实在没理解第七点,望详解,谢谢。
May 13th, 2009 on 13:39
对于第五个测试例子,我用Firebug+httpwatch测试都是同时请求了两个背景图!我FF版本是3.0.10
May 13th, 2009 on 15:01
亲自测试,“display: none” firefox是请求的
之前也觉得奇怪,明明隐藏了Tag,为什么还会请求生成
May 13th, 2009 on 15:05
非常喜欢这类文章,希望博主多发
May 13th, 2009 on 16:49
firefox在图片SRC切换的时候,即使是已经预载入过的图片也会产生请求,之前在新浪奥运的时候做了个图片浏览器,直接修改的IMG的SRC地址来实现切换显示,结果导致了服务器产生了大量请求数,只能被迫改为Z-INDEX数值的切换来显示图片。不知道哪位大虾有解决方案。
May 13th, 2009 on 17:21
关于 重复背景 一段
根据一直以来的常识,IE6默认不缓存背景图片的(bug??),一般要
<!–[if IE 6]>
<script type=”text/javascript”>
document.execCommand(“BackgroundImageCache”, false, true);
</script>
<![endif]–>
May 13th, 2009 on 20:31
不错的测试。Good job!
May 14th, 2009 on 15:53
不错的总结,比较全面。
从7.5版开始,Opera一直是我的首选浏览器。
目前 Opera 的缺点就是 javascript 引擎的速度慢了点,期待 Opera 10。
May 16th, 2009 on 20:46
@葫芦居士:好像和服务器配置有关,我在本地apache下测试,能捕捉到你说的问题,但将测试页面放到blog空间后,又没问题了,比如:
http://lifesinger.org/lab/2009/img_src_cache_test.html
May 27th, 2009 on 10:43
重复不重复请求是和服务端对图片设置缓存或者304等header信息有绝对关系的。
而且像IE6这种弱智浏览器,即使设置了缓存,如果是相同图片的话(包括CSS用到的背景图)都会发起不同的请求。
May 28th, 2009 on 11:53
@letle: 在服务器正常配置下,ie6对重复图片不会发送不同的请求。
June 3rd, 2009 on 10:54
不错,学习
November 19th, 2009 on 20:54
最近遇到个小问题,测了下二和三,得到的结论和你不一致
在firefox3.5中无缓存的返回状态200的时候重复多少次就有多少个请求,用firebug和fiddler测的
November 19th, 2009 on 22:20
@rukey67: 在文章最后番外里有讲:
3. 我的Firefox对于重复图片和重复背景,会产生重复请求。禁用了所有扩展,问题依旧。有知详情者,还望告知。
你的问题和我一样,我怀疑是 about:config 里某项配置导致。原版 Firefox 默认配置下不会产生重复请求。
March 4th, 2010 on 23:08
长知识了,
现在有个问题想请教一下,有关hover的:
以前项目中,如果没有添加ssl加密时(https),是不会出现闪烁效果的,
但是加完之后,就出现了,每一次hover总会重新请求背景图片。
April 30th, 2010 on 14:54
学习当中。
May 24th, 2010 on 14:42
你好,请问有什么办法可以让已存在的img src 不请求,请问用js可以控制请求与否吗?
谢谢
leave a reply