http2 同一个域名建立 2 条 TCP 连接的可能情况

答案

如果 HTML 标签(比如script或link等)上设置了crossorigin="anonymous"的话,跟没有设置该属性的请求是不会共用连接的。

问题

前几天打开线上网站发现等得时间非常久,于是打开控制台刷新了下,有个脚本居然花了 50 多秒才下载下来:

image.png

是可忍,孰不可忍?

排查

从图上可以看到,大部分时间都花在 stalled 阶段,看官方的解释,说停留在 stalled 阶段的原因与排队阶段是一样的,而排队阶段可能由于下列原因造成阻塞:

  • 有更高优先级的请求
  • 已经打开了 6 个 TCP 连接,这是 HTTP/1.0 和 HTTP/1.1 协议的限制
  • 浏览器正在磁盘缓存中分配空间

第一点显然不成立,看图上那一段时间只有这一个请求。至于第二点,我这个站点是 https 协议,静态资源都在 CDN,已经是 http2 了,也不成立。第三点也不太合理,为什么这个请求要花这么久去分配空间呢?在上面那张图上,那个请求前面的 3 个 js 文件和 2 个 css 文件都是同一个 CDN,其他请求都没这么久的,就这个特别久。而且清除浏览器连接缓存后刷新页面,还有一定概率能重现。不过有可能不是阻塞在 stalled 阶段,也可能是 TCP 连接阶段:

在这里插入图片描述

一分多钟才建立连接,这网站还能用?

后面又试了几次,有 2 次甚至直接白屏了,控制台报了个超时的错误,是 webpack 打包后的代码里抛出来的(该 js 文件是前面一个 js 文件动态插入文档的):

image.png

这种情况网络面板是不会展示请求阶段耗时的,只有一个 stalled 的阶段,也不知道是哪里出了问题。

然后我突然想到,CDN 明明都是 https 协议,按道理应该多路复用,只需要一条 TCP 连接才对,为什么会出现重新建立连接的情况?

然后设置展示 connection ID 那一列,又多次刷新,发现每次都是这一个资源与别的资源的 ID 不一样。于是开始猜这个猜那个,比如请求数限制、延时请求、响应头字段之类的,也没看出来什么东西。

然后看了下公司官网,也有这种同个站点多条连接的情况。又看了下其他知名站点,比如腾讯网、新浪网之类的,多数真的是一条连接用到底,这种情况还挺难找的。

最后终于发现,如果 HTML 标签(比如scriptlink等)上设置了crossorigin="anonymous"的话,跟没有设置该属性的请求是不会共用连接的。

然后重点就是研究这个 crossorigin 属性了,坦白说,还没搞懂。只知道不设置该属性、值设为use-credentials都是一样的效果,会复用连接,只有anonymous是特例。甚至 clone 了 chromium 的源码下来,想一探究竟,最终还是不得不向现实低头:这种事情不是我能把握的……

回到开头的问题,观察到线上 webpack 打包出的 html 文件的script标签都是带了这个属性的,但是上面那个动态插入的 js 是没有的。这下就容易了,去 webpack 官方文档一搜就出来了:

image.png

不过还是不明白, 为什么当时测试的时候到了这个 js 建立连接的时候有一定概率会等很久,前面的都很快,难道是我刷新次数不够多?

也不知道是不是还有其他情况,会建立多条 TCP 连接的……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值