Web性能优化-什么是连接复用
Web 性能指标
web 性能优化到底在优化什么?
你可能会说优化的是用户体验,但用户体验是不可测量的,我们必须把用户体验变成可测量的指标,这些指标包括:
- 用户按下回车
- 由内容出现时(一般3秒之内还没有内容出现,用户就会比较焦虑,会关掉页面)
- DOM ready 事件发生(dom content loading ,代表 HTML 内容全部解析完,js 也基本执行完了,但并不保证图片已经全部加载和 css 样式加载完,就是 network 里面那跟蓝色的线)
- 页面可交互(JS 都执行了,并且把事件都绑定了,用户点击按钮不会出现没反应的情况)
- onLoad 事件发生
- 动态资源加载完毕
DNS prefetch
DNS 预解析
假设 index.html 的部分代码为:
<script src="http://a.com/1.js"></script>
<script src="http://b.com/1.js"></script>
那么过程就是首先对 a.com 进行 dns 查询 => 拿到 ip 地址以后 => 下载a.js => 对 b.com 进行 dns 查询(一定会等 a.js 下载执行完毕后才开始) => 拿到 ip 地址以后 => 下载b.js
如果 a.com 和 b.com 同时先进行 dns 预解析,那么就能节省一定的时间
优化(两种方法)
前端
<link ref="des-prefetch" href="https://a.com/" >
<link ref="des-prefetch" href="https://b.com/" >
后端
// index.html 的响应头里写
Link: <http://a.com />; rel=dns=prefetch
TCP 连接复用
正常流程:开启 TCP => 请求 => 响应 => 关闭 => 开启 TCP....
可以发现一直在重复开启关闭,为何不复用呢,开启后就不关闭了,节约多次重复开启关闭的时间。
实现
// 请求头
Connection: keep-alive
// 响应头
Connection: keep-alive
但是如果服务器一直开着将会非常占用资源,用户一多,服务器就顶不住了,所以一般都会在设置一个超时时间,如果超过多少秒还没有再次发起连接,那么将会强制关闭。
// 请求头
KeepAlive: timeout=5, max=10
// 响应头
KeepAlive: timeout=10, max=100
客户端和服务器都可以设置这个字段,两者可以不一样,timeout 表示多少秒,max 表示多少次,一般来说聪明的浏览器会以服务器为准(尊重服务器的能力),而傻一点的浏览器(如:IE)就坚持自己为准
前端怎么加 keep-alive?
如果用的 http/1.1 以上,会自动加。
也就是基本上不用去优化了。
并行化连接
因为连接复用是串行的,当同时处理多个请求的时候还是太慢,所以需要并行连接。
也就是说同时建立好几个请求(一般浏览器会设置最大数量,同一个域名一般 4-12 个)
那么连接复用就没有用了吗?
答案是不会,因为浏览器设置了连接上限,如果超出的连接数,那么剩下的就会等待上一个请求结束后再进行复用。
🌰:
相同的 id 代表连接复用
HTTP 管道化
浏览器默认关闭,可能会有 BUG
🌰:
|一个 http 管道-------------------------
|| 1.css ----- 响应
| | 2.css ----- 响应
| | 3.css ----- 响应
|--------------------------------------
当在管道中发起(接近同时)三个请求时,会有如下问题:
- 浏览器必须要按照相当的顺序返回响应,否则会对应不上,不像并行一样,每次都是新的连接一一对应。
- 如果 1.css 因为网络波动特别慢,那么 剩下的必须得等 1.css 响应结束才可以继续,因为一旦 2.css 提前响应了就会被浏览器错误的当成 1.css 的响应。
所以他会导致请求之前的顺序依赖,导致这样的并行没法导致最快的速度,所以一开始的 http 设计并不能满足现在的需求,所以需要升级为 HTTP/2.0