前端网络与优化
- 三次握手、四次挥手
这里先弄清楚几个报文的含义
-
SYNC 同步序列
-
ACK 确认
-
FIN 结束
- 三次握手
- 发起方 — > SYNC = 1, ACK = 0 —> 接收方, 报文含义就是发起连接,等待回复
- 接收方 —> SYNC = 1, ACK = 1 —> 发起方,报文含义就是发起连接,收到了回复
- 发起方 —> SYNC = 0, ACK = 1 —> 接收方, 报文含义连接同步完成, 收到了回复
- 四次挥手
- 发起方 —> Fin = 1 —> 接收方,报文含义 准备结束
- 接收方 —> ACK = 1 —> 发起方 报文含义收到结束消息,正在处理中
- 接收方 —> Fin = 1,ACK = 1 —> 发起方 报文含义处理完成,等待回复
- 发起方 —> ACK = 1 —> 接收方 报文含义收到回复
- 三次握手
实际上中间还有 seq
(确认号)、ack
(发送数据的序号),只是以上比较容易理解与记住这个过程
-
HTTP 的演进
- http1.0 升级到 http1.1
- 改进:
- 默认启用 Connection: keep-alive, 可复用TCP连接
- 同一连接允许多个请求连续发送 (但是响应还是按顺序响应,易阻塞)
- 支持动态内容,流式响应
- 更灵活的缓存策略( Cache-Control 、 ETag等)
- 问题:
- 同一连接串行响应,队头阻塞问题
- 同一连接:源IP + 源端口 + 目标IP + 目标端口 都需要相同
- 请求1 ->请求2 -> 请求3 ->返回1 -> 返回2-> 返回3 , 可以发送多个请求,但是返回还是按顺序返回,返回阶段如果 返回1响应处理慢,就会导致阻塞后面的响应,这就是队头阻塞
- 会开多个TCP连接浪费资源(为了缓解队头阻塞的问题,不是解决方案)
- 同一连接串行响应,队头阻塞问题
- http1.1 升级到 http2.0
- 改进:
- 分帧概念,文本协议改进成二进制格式,更高效、可多路复用;
- 一个TCP 连接可同时传多个请求/响应流
- 减少重复header传输,提升效率
- 客户端可指定资源加载的优先级
- 问题
- 最严重的问题就是TCP 一旦丢包,会在传输层出现队头阻塞
- 多个请求流(如流A、流B、流C)共享同一个TCP连接。当TCP包2(包含流B的数据)丢失时,即使TCP包1(流A)和包3(流C)已成功到达,TCP协议要求数据必须按顺序交付,导致所有流的交付都被阻塞,等待包2的重传。
- 最严重的问题就是TCP 一旦丢包,会在传输层出现队头阻塞
- http2.0 升级到 http3.0
- 改进:
- 因为运用TCP实际上就是为了安全以及传输的准确性,结果发现达不到预期,弃用TCP,基于谷歌QUIC协议处理
- 丢包只会影响单个流,不阻塞其他流
- 0 握手连接恢复
- 建立连接仅需一次往返
- 缺点:
- 实现更加复杂
- 对中间设备的兼容性要求高
-
https 对于 http 的区别
- https 建立连接过程(非对称加密)
- 客户端发起连接,并告诉服务端自己支持的加密方式
- 服务端返回SSL证书(包含公钥)
- 客户端验证证书
- 验证通过后客户端会生成一个会话密钥,通过服务端的公钥加密后发送给服务端
- 服务端使用自己的私钥去解密,得到会话密钥
非对称加密的有点就是安全,私钥在服务器,不容易被黑客截取用来解密,缺点就是耗时长,所以在建立连接后采用对称加密的方式
- https 的数据传输过程就是服务端和客户端的请求与响应都使用会话密钥来进行加密解密,这里就是对称加密
- https 建立连接过程(非对称加密)
可以看出来不管是TCP 连接又或是https的加解密都是耗时任务,所以我们的优化方案就有合并请求、长连接、区分资源优先级(fetchpriority, loading)、利用缓存(需后端配合)等
-
域名解析
- 域名解析过程(每个步骤查找是否有缓存,有则停止没有则继续往下)
- 浏览器查找自己
- 本地hosts和dns
- 路由器
- 运营商dns
- 根域名服务器
- 优化
- 使用dns-prefetch提示浏览器提前解析域名
<link rel="dns-prefetch" href="xxx">
- 使用prefetch在浏览器空闲时间加载资源
<link rel="prefetch" href="xxx" as="fetch">
- preload是让浏览器以高优先级优先加载资源
//例如使用字体文件<link rel="preload" href="/fonts/myfont.woff2" as="font" crossorigin><style>@font-face {font-family: 'MyFont';src: url('/fonts/myfont.woff2'); /* 此时字体已在缓存 */}</style>
- 请求的资源根据距离不同有不同的时间差
- cdn多节点部署(减少物理层面距离)
- cdn缓存策略 (静态资源可以缓存,减少传输次数)
-
代理
- 正向代理(掩盖真正的请求者,例如科学上网)
- 反向代理 (掩盖真正的返回者,例如配置nginx)