各浏览器对页面外部资源加载的策略

这个总结来源于一次优化的请求,最初某个页面的加载十分缓慢,load事件迟迟无法触发,因此希望可以通过对静态文件分域名等方式对页面的外部资源进行优化,拿得load事件尽可能早地触发。

于是我查看了页面的源码,并对外部资源进行了整理,基于下面2个理念画出了一个推测的瀑布图:

  • 浏览器对同一个域只能并发2个HTTP请求 - 网上盛传已久。
  • javascript文件的加载会阻塞浏览器其他资源的加载 - 同样网上盛传已久。

然而,当我看到各浏览器中实际的瀑布图时,我知道自己又犯了一个简单的错误:太过相信所谓的权威和大众的声音,而没有更早地进行实践来检验理论的正确性……

本篇文章就使用几种流行的浏览器,针对同一个页面的外部资源加载过程进行分析,推测各浏览器加载外部资源的策略、特征,并最后给予一定的比较和总结。

测试样例

测试的页面结构如下:

  • head
    • 1.css + 1.js
  • body
    • 1.jpg + 2.jpg + 2.js + 2.css + 3.jpg + 4.jpg + 3.css + 3.js + 5.jpg + 6.jpg

共12个外部资源,加上页面本身,一次完整的加载一共有13次HTTP GET请求。

针对每一个外部资源,服务器首先会休眠5秒的时间,随后再返回相应的内容,以方便查看整个外部资源的加载过程。

测试的浏览器如下:

  • IE6
  • IE8
  • Firefox3.6
  • Firefox4.0 beta12
  • Chrome 8
  • Opera 11

IE6

IE6的瀑布图非常传统,其特征有:

  • 各资源按照在HTML中出现的顺序进行加载。
  • javascript文件会阻塞其后所有资源的加载。
  • 最大并发HTTP连接数为2个。

可见网上盛传的2个“误区”都来自IE6统治浏览器市场的时代,针对IE6的优化太多太多,大家也就习惯性地将这些结论作为公理来使用了。

IE8

和IE6完全不同的瀑布图,其特点有:

  • 最大并发HTTP连接数为6个。
  • javascript文件已经不会阻塞其他资源的加载,甚至多个javascript文件可以一起加载,并且会保证执行的顺序。
  • 会分析HTML结构,优先下载script和link标签定义的外部资源。

Firefox3.6

和IE8的几乎完全一样:

  • 最大并发HTTP连接数为6个(可在about:config中修改)。
  • javascript文件不会阻塞其他资源的加载,多个javascript文件可以一起加载。
  • 会分析HTML结构,优先下载script和link标签定义的外部资源。

Firefox4 beta12

不知是因为设计理念上的不同,还是因为beta版未照顾到这一块,Firefox4反而退化了,和Firefox3.6的区别主要体现在对资源类型的处理上,Firefox4不再严格地优先下载script和link标签定义的外部资源,而是按照HTML结构中出现的顺序来进行加载。

Chrome8

Chrome自带的工具不能很清楚地表示各请求的开始时间,所以使用了Fiddler的瀑布图,从图上可以看出,Chrome也是比较特立独行的一位,其特点有:

  • 最大并发HTTP连接数为6。
  • head部分的资源会单独下载,且阻塞body中的其他资源的加载。
  • 会优先加载script和link标签定义的资源。

Opera11

先报怨一下,Dragonfly不怎么好用来着……Opera的资源加载也比较有特色,而且很难看出规律,只能大致总结一下:

  • 最大并发HTTP连接数为5(网上有说原先版本是4)。经过网友的指正,Opera的最大并发HTTP连接数默认为16,可在opera:config - Performance - Max Connections Server查看和修改。
  • javascript文件的加载会阻塞其他script和link标签定义的外部资源的加载,如图中的2.js。但不会阻塞图片等其他资源的加载,如图中的3.js。
  • 会一定程度上对资源的优先级进行优化,但由于javascript文件要阻止后续部分资源的加载,又为了充分利用最大HTTP连接数,因此不能严格先加载所有的script和link标签定义的资源,导致瀑布图上各类型资源有相互穿插,难寻规律。

总结

  • 抛开IE6不论的话,除非是在线相册之类外部资源非常多的页面,不然没必要去追求静态资源的分域名优化。
  • 针对IE6进行静态资源分域名优化时,要严格注意javascript文件对后续资源的阻塞,进行精确计算和设计后保证资源最完美地分域名存储,以提供最大并行度。
  • 鉴于Chrome对head部分的资源会独立加载,当head部分用不满6个HTTP并发数时,是否可以将资源移到body中呢?在body中的资源又会引起其他的问题,需要谨慎考虑。
  • Opera的行为比较怪异,似乎主动设计了一个很麻烦的算法,不过考虑到其占有率,就先放在一边吧……而且号称最快的浏览器的Opera,在加载javascript文件时竟然如此笨拙……
  • Firefox4 beta12的行为让人无法理解,看来要追踪RC版是否还存在这个问题,如果存在的话可以考虑找Mozilla报个问题了。

对各浏览器加载外部资源的策略的掌握,是WPO的基本元素,虽然一直想当一个WPO的专家,却在这方面迟迟不愿实践,实在有愧于自己的理想……

最后,如果有哪位朋友了解Opera对资源加载的具体策略的,还请提供一下,以便有更清晰地认知,谢谢~!

本文永久地址:http://www.otakustay.com/browser-strategy-loading-external-resource/

posted @ 2011-03-08 17:33 Gray Zhang 阅读(1584) 评论(25) 编辑 收藏

 回复 引用 查看   
#1楼2011-03-08 18:02 | xming4321      
好东西 这里忍不住赞一个!
改变了我的看法 呵呵

 回复 引用 查看   
#2楼2011-03-08 18:25 | 岑安      
这个东西,收藏了...我自己太懒了
 回复 引用 查看   
#3楼2011-03-08 18:33 | 熊在路上      
似乎opera 11 的最大连接数默认为16, 而且可以修改~~
 回复 引用 查看   
#4楼[楼主]2011-03-08 18:37 | Gray Zhang      
@熊在路上
感谢指正,我又犯了凭直觉不考证的错,其实在opera:config - performance - max connetions server里就能查看和修改的
但是如果opera的最大并发数为16的话,这个瀑布图就更不可思议了,为什么不将其他的图片资源也前置,以便和阻塞后续资源的2.js一起加载呢……

 回复 引用 查看   
#5楼2011-03-08 19:16 | Keep Walking      
谢谢分享,呵呵
 回复 引用 查看   
#6楼2011-03-08 19:45 | lxforever      
学习了
 回复 引用 查看   
#7楼2011-03-08 20:38 | 加油!棒棒糖      
楼主辛苦了。还是实验有说服力啊。
 回复 引用 查看   
#8楼2011-03-08 20:50 | jelle      
非常赞。楼主辛苦 学习了。
 回复 引用 查看   
#9楼2011-03-08 22:37 | snandy      
赞一个!事实说明一切。

www.yottaa.com

这家小外企是基于云计算专门做WPO的。

 回复 引用 查看   
#10楼2011-03-08 22:41 | Pola'ZeYu      
额,以前貌似在一本书上看了一些类似的知识,貌似还比较详细,貌似叫高性能网站建设进阶指南
 回复 引用 查看   
#11楼[楼主]2011-03-08 22:56 | Gray Zhang      
@Pola'ZeYu
这本书就在我的书柜上,就是这本书告诉我“HTTP1.1协议建议浏览器并行下载数为2个”,也是这本书告诉我“脚本下载会阻塞后续资源的加载”的……难道这本书又有了新版么,如果没有更新的话,这本书很多内容都是过时的

 回复 引用 查看   
#12楼2011-03-08 23:16 | Pola'ZeYu      
那应该是过时的了,不过那里也提到,降级用HTTP 1.0的话,并发数可以提高,貌似也是有的浏览器六个
 回复 引用 查看   
#13楼[楼主]2011-03-08 23:34 | Gray Zhang      
@Pola'ZeYu
对,HTTP1.0的连接数限制更多,因为没有keep-alive的功能。但是又由于HTTP1.0没有keep-alive,即http pipeline的功能,导致每个资源都要有一次TCP的连接过程,往往比带连接数限制的HTTP1.1还不堪

 回复 引用 查看   
#14楼2011-03-09 09:32 | 真爱无悔      
多谢分享
 回复 引用 查看   
#15楼2011-03-09 09:38 | Tony Zhou      
引用Gray Zhang:
@Pola'ZeYu
这本书就在我的书柜上,就是这本书告诉我“HTTP1.1协议建议浏览器并行下载数为2个”,也是这本书告诉我“脚本下载会阻塞后续资源的加载”的……难道这本书又有了新版么,如果没有更新的话,这本书很多内容都是过时的



http1.1很早的事情了,现在的浏览器都抛开这个限制

 回复 引用 查看   
#16楼2011-03-09 09:40 | 冰封e族      
值得学习,顶楼主
 回复 引用 查看   
#17楼[楼主]2011-03-09 10:34 | Gray Zhang      
@Tony Zhou
嗯,但现在的HTTP版本依旧是1.1,而且RFC2616还真的明确推荐只开2个TCP连接,可在下面地址的最后一段找到
http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4
引用Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy

 回复 引用 查看   
#18楼2011-03-13 22:00 | skyaspnet      
抛开IE6不论的话,除非是在线相册之类外部资源非常多的页面,不然没必要去追求静态资源的分域名优化。

张大哥好,对于大访问量的网站还是非常有必要的,因为过多的静态资源文件下载等I/O操作对CPU和内存是有消耗的,极端情况下会影响到对正常的程序处理,有条件的话还是需要分离一下的

 回复 引用 查看   
#19楼2011-03-23 17:45 | 蛙蛙王子      
哥,有新浪微博不?现在只关注前端了吗?
 回复 引用 查看   
#20楼[楼主]2011-03-23 18:01 | Gray Zhang      
@蛙蛙王子
几乎只关注前端,但是.net不会落下太多就是了~
我只用TX的微博,帐号int08h

 回复 引用 查看   
#21楼2011-05-19 17:14 | Randy0528      
静态资源分域名优化,还有一个原因是去除cookie。

同域名的情况下,静态资源在请求时也会自带cookie信息。

 回复 引用 查看   
#22楼2011-05-19 17:15 | Randy0528      
引用skyaspnet:
抛开IE6不论的话,除非是在线相册之类外部资源非常多的页面,不然没必要去追求静态资源的分域名优化。

张大哥好,对于大访问量的网站还是非常有必要的,因为过多的静态资源文件下载等I/O操作对CPU和内存是有消耗的,极端情况下会影响到对正常的程序处理,有条件的话还是需要分离一下的

他讲的分域名应该是指独立域名吧。呵呵。我猜的:)

 回复 引用 查看   
#23楼[楼主]2011-05-19 17:15 | Gray Zhang      
@Randy0528
感谢补充!这一点确实是我当时的疏忽,虽然平时工作过程中都会注意到,但真正写文总结时却会忽略……

 回复 引用 查看   
#24楼2011-05-19 17:16 | Randy0528      
static.xxx.com
和static.xxx1.com两个域名对于cookie还是不一样的。

 回复 引用 查看   
#25楼[楼主]2011-05-19 17:18 | Gray Zhang      
@skyaspnet
有个概念需要指正一下,分域名和分主机是完全没有关系的2个事情,N个域名可以同时对应一台主机,相反1个域名后面也可以由N台主机服务
所以分域名这条规则是怎么也扯不到服务器的资源消耗上的……