我们上网使用HTTP协议,HTTP协议的基石就是RFC 2616,在这个文档的8.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. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.
我们的浏览器就是HTTP协议的客户端,这句话实际上就是说浏览器不应该同时保持超过2个对同一服务器(实际上是domain)的连接。当年制定这个规则的时候,也是考虑到网络基础设施还很不发达,如果不做此限制,让客户端可以开任意多连接到某个服务器,那这个服务器很可能很快资源就被耗尽了。
时至今日,网络设施已经今非昔比,让一个浏览器最多保持对一个domain的两个连接显得不合时宜了。
在考虑提高网站性能的时候,必须要考虑到这一点,比如如果你的网页上有大量图片,那最好不要把这些图片资源放在同一个域名(domain)下,不然假如有100个图片,每个图片下载需要100毫秒,那么依靠这两个连接,总共要花费(100/2)*100毫秒=5秒,但是假如你能够把这100个图片分布到10个域名下,理论上,只需要花费(100/(2*10))*100毫秒=500毫秒级可以把图片全部下载完。当然,最优情况是这100个图片平均分布在50个域名下,理论上100毫秒就全搞定了,我说的是理论上,因为要是你的浏览真的同时下载这么多图片,速度还是受带宽限制的。
虽然网站这一方可以采取措施抵消这个最大连接数的负面影响,但是毕竟麻烦。事实上,浏览器生产商早就意识到这个连接数不现实了,所以虽然规矩上说这个数字应该是2,但是大家都纷纷不守规矩,Steve Souders有一个网页显示当前主要浏览的这个参数限制:
| Browser | Max Connections / Host |
| Chrome 1.0 | 6 |
| Chrome 2.0 | 6 |
| Firefox 3.0 | 6 |
| Firefox 3.5 | 6 |
| IE 6 | 2 |
| IE 7 | 2 |
| IE 8 | 6 |
| Safari 3.2 | 4 |
| Safari 4.0 | 4 |
很明显大家都已经无视2这个限制了,唉,IE 7居然也是2,同时期的竞争对手浏览器都不守规矩了,为什么还傻傻的遵守RFC呢?当因为这个原因导致IE 7比其他浏览器慢,用户才不管你是不是互联网上遵纪守法的好公民呢。还好到IE 8的时候,IE组终于知道随波逐流了。
仿照Steve Souders的网页,我也做了一个网页测试这个参数,点击这里可以得到你正在使用的浏览器的对一个域名的最大连接数。
这个测试的基本原理,就是在网页里内嵌10个图片(<img>),每个img的src都是同一域名下的一个资源,为了防止误差,每个图片资源都需要花费比较长的时间才能下载(我选的是5秒),在客户端,通过javascript统计一下有多少图片在9秒钟之内load完成,就知道这个最大连接数了。
一个问题是如何让一个图片如何花5秒钟时间下载,简单的方法就是让图片的URI指向一个PHP页面,我管它叫slow_page.php,在PHP里故意等待5秒,然后从一个外部图片文件读取内容返回,我的slow_page.php这么写的:
<?php
sleep(5);
$img = file_get_contents("wario.jpeg");
header("content-type: image/jpeg");
echo $img;
?>
还有一个问题是防止浏览器cache这些图片,因为这些图片内容其实都是一样的,得有个办法让浏览器认为他们不一样,对每个<img>都去服务器端取一次图片内容。我们可以让slow_page.php返回的HTTP response中包含不要缓存的header,但是有个更简单的方法,那就是让所有的图片的URI都不相同,虽然图片都可以通过http://test.morgancheng.com/test-max-connection-per-host/slow_page.php访问,但是在http://test.morgancheng.com/test-max-connection-per-host/中,我们故意让每个URI后面都有一个不同的query string,这样浏览器就会认为每个图片都不相同,缓存的作用也就被破坏了。
<?php
$timeStamp = time();
for ($i=0; $i<$imageCount; ++$i) {
$imgUrl = "slow_page.php?nuance=".$timeStamp.$i;
echo "<img src=$imgUrl onload='onImgLoaded()'/>";
}
?>
下面是通过Firefox 3.5访问http://test.morgancheng.com/test-max-connection-per-host/的结果,可以看到Firefox 3.5的每个域名的最大连接数是6。
相关文章:
- 你的浏览器能能同时保持对一个域名的多少连接(2)?
- 浏览器战争进展:Google Chrome取代Apple Safari成为第三浏览器
- Google发布Chrome 4.0正式版
- Chrome Frame in IE:这是个狠招
- 微软将让欧洲用户自己选择浏览器:IE丧失捆绑优势
分享到: 开心网 豆瓣网 人人网 Google书签 Del.icio.us
2009年9月14日, 星期一 20:03:15
[...] 你的浏览器能能同时保持对一个域名的多少连接? | 巴别塔上的雇工. [...]