你的浏览器能能同时保持对一个域名的多少连接?

发表于2009年9月13日, 星期日此文属于 技术体会

我们上网使用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。

firefox_test_connection

相关文章:

  1. 你的浏览器能能同时保持对一个域名的多少连接(2)?
  2. 浏览器战争进展:Google Chrome取代Apple Safari成为第三浏览器
  3. Google发布Chrome 4.0正式版
  4. Chrome Frame in IE:这是个狠招
  5. 微软将让欧洲用户自己选择浏览器:IE丧失捆绑优势

分享到: 开心网 豆瓣网 人人网 Google书签 Del.icio.us

 

目前已有一篇评论,还有板凳可坐

  1. 你的浏览器能能同时保持对一个域名的多少连接(2)? | 巴别塔上的雇工说:

    [...] 你的浏览器能能同时保持对一个域名的多少连接? | 巴别塔上的雇工. [...]

我来评论两句