并发请求介绍

由于端口数量和线程切换开销的考虑,浏览器不能无限量的并发请求,再者将所有请求一起发给服务器,也很可能会引发服务器的并发阈值控制而被 BAN,而另外一个控制的原因是 keep alive 技术的存在使得浏览器复用现有连接和服务器通信比创建新连接的性能要更好一些,出于客户端和服务端因素的综合考虑,因此衍生出来了并发限制。

以下为各大浏览器并发请求限制的数量(只在同一与域名下有效)

浏览器HTTP 1.1HTTP 1.0
IE 6, 724
IE 8, 966
Firefox 1366
Chrome 206?
Safari 5.1.76?
Opera 11.648?

并发请求测试

以上数据来源于网络,以下针对与 Chrome 65Firefox 58 分别进行了测试,思路是首先写一个循环 12 次的请求,打开控制台的 Network 版面,使用录屏软件进行录取,然后慢放帧查看请求的状态,其实不用录屏直接看也能看出效果,眼睛要盯紧一点。

新建一个测试网页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>

<script type="text/javascript">
const startTime = Date.now();
const q = new Array(12).fill(0).map(v => {
const p = new Promise((r) => {
const xhr = new XMLHttpRequest();

xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
r();
}
};
xhr.open('GET', 'https://hacker-news.firebaseio.com/v0/topstories.json', true);
xhr.send();
});

return p;
});

Promise.all(q).then(rs => {
console.log(Date.now() - startTime);
});
</script>

</body>
</html>

以下为录取 Chrome Network 控制版面的慢放帧,可以看出在 12 个请求中,先发出前 6 个请求,后 6 个处于 pending 状态,当前 6 个请求完成时余下的请求才发出。

以下为使用 Firefox 的测试结果,可见和 Chrome 的一样

修改并发请求数量

浏览器这样做出发点是好的,但有时候我们想要个性化定制(比如做个插件开个挂之类的😈)就没那么方便了,那能不能修改限制上限呢?

  1. Chrome 的并发请求数量是不能修改的,因为已经固定写到源码中了,具体可以查看:https://chromium.googlesource.com/chromium/src/+/65.0.3325.162/net/socket/client_socket_pool_manager.cc#44,可以使用 Firefox,如果非要修改可以尝试修改源码然后自行编译。
  2. Firefox 是可以修改的,想要修改首先在地址栏输入 about:config,搜索 http.max 关键字,network.http.max-connections 为全局 HTTP 同时最大的连接数量,默认为 900;network.http.max-persistent-connections-per-server 为单个域名最大链接数量,默认为 6,击双此列可以进行修改。

这里我们把 network.http.max-persistent-connections-per-server 从 6 修改到 8 然后再次进行测试

我们可以看到请求 topstories.json 第一次请求发出的 8 个,剩余 4 个处于等待状态,当 8 个请求完成时余下 4 个才发出,这里测试的时候网络比较稳定,前 8 个几乎同时发出和返回,所以后 4 个几乎一块发出。

我们分别进行两轮测试,分别在看下控制台打印的 500 个请求总共消耗的时间(单位ms)进行结果再次确认

并发 6并发 12
1165548631
2180379427

结束语

随着现在网站越来越丰富化,并发 6 个请求可能已经满足不了千变万化的需求,这时我们可以使用不同的域名进行资源分离,这样就可以绕过单个域名只能并发请求 6 个资源的限制,在加上 dns-prefetch 特性来提升网站打开速度而又不丢失站点的丰富性,简直完美 👏👏👏。

以上只测试了 Chrome 65Firefox 58 有兴趣的可以使用这种方法测试其他浏览器,测试完欢迎回来交流。

至此结束,感谢阅读。