0x11 网络请求响应优化

Review

  1. 2024-10-05 11:11

[!Summary]

  1. 缓存
  2. DNS
  3. TCP
  4. CDN
  5. 负载均衡
  6. 服务端
  7. HTTP协议
  8. 资源:资源数量 & 资源大小

一、Introduction #

1: 缓存 #

  1. 浏览器缓存 [[HTTP Caching]]
  2. DNS缓存
  3. Service Worker + API
  4. 代理服务器缓存:防止端点服务器频繁请求源站
  5. 分布式缓存
  6. 数据库缓存
  7. 服务器缓存(RedisMemcached

网站应该缓存页面一小段时间,至少在使用HTTP/2时,因为304响应比200响应的开销低很多。

Service Worker可以查看、回复,或者更改HTTP请求。 当网站使用Service Worker时,Service Worker可以中断请求,当离线时,其可以返回一个之前缓存的资源版本。这就使得在离线时也能使用缓存的网站,像移动端应用一样。

2: DNS #

详见 [[DNS-Domain Name System]]

  1. DNS预解析: [[HTML attribute rel value]]
  2. DNS缓存优化
  3. 资源的域名合理分配,减少域名数量
  4. 稳定可靠的DNS服务器
<link rel="dns-prefetch" href="abc.com" />

DNS解析性能优化方案

  1. 设置合理的TTL时间
  2. DNS多点就近部署架构升级
  3. 基于 Anycast 的DNS解析架构 —- 未来DNS优化方向

DNS查询有一个存活时间(TTL),所以网站不能过早地进行DNS查询(比如查询你在下一个页面会用到的域名),因为当TTL过期时,DNS查询可能要再重复一次。通常会有300秒或者更长的TTL,并且理想情况下,你的网页加载时间不会超过5分钟,所以它对于你的页面资源来说是安全的。

3: TCP #

preconnect(提前连接)做了进一步延伸。它除了提前做DNS解析以外,还提前创建连接,这可以节省创建新的连接时的TCP和HTTPS开销。不要太早使用preconnect,如果有段时间不用它,TCP慢启动算法会介入,这会降低传输速度,更糟的是,连接可能会被断开。

3.1: 拥塞控制算法优化 #

  1. 选择合适的算法:根据网络环境和应用场景选择合适的拥塞控制算法(如TCP RenoTCP CubicTCP Vegas等),以避免网络拥塞,提高传输效率
  2. 动态调整参数:根据网络状况动态调整拥塞窗口大小、重传超时时间等参数,以适应网络变化。基于不同的网络环境,优化数据包的大小,以减少数据因传输丢失或者被破坏产生的重传,从而提高传输效率

3.2: TCP参数调优 #

  • 初始拥塞窗口(cwnd): 适当增大初始拥塞窗口,可以加快连接建立后的数据传输速度。
  • 慢启动门槛: 调整慢启动门槛,可以控制网络拥塞的发生。
  • 重传超时时间(RTO): 合理设置RTO,可以避免丢包重传次数过多,提高传输效率。
  • 快速重传: 启用快速重传机制,可以加速丢包的恢复。Early Retransmit (ER) 比 Fast Retransmit 更优秀,在收到第一个重复确认(duplicate ACK)时就立即重传丢失的数据包,而不是等到收到三个重复确认再重传。

3.3: TCP快速打开(TFO) #

  • 启用TFO: 在支持TFO的系统上启用TFO,可以减少TCP连接建立的时间。

3.4: TCP选项优化 #

  • Selective Acknowledgements(SACK): 启用SACK,可以更精确地指示接收方已经收到的数据,提高重传效率。
  • Timestamp: 使用Timestamp选项可以提高时钟同步精度,从而更准确地估计RTT。

3.5: 网络接口优化 #

  • MTU调整: 调整最大传输单元(MTU)的大小,以适应网络链路特点,避免分片。
  • TCP offload: 使用TCP offload引擎,将TCP协议的处理任务从CPU转移到专门的硬件上,减轻CPU负担。

3.6: 网络环境优化 #

  • 减少网络延迟: 优化网络拓扑结构,减少路由跳数,降低延迟。
  • 提高网络带宽: 增加网络带宽,提高数据传输速率。
  • 网络传输链路的优化

3.7: 其他优化 #

  1. TSO (TCP Segmentation Offload) TCP分段卸载。将TCP数据包的分段工作从CPU转移到网卡上,从而减轻CPU的负担,提高网络传输性能。

工作原理

  • 大数据包生成: 应用程序生成一个较大的TCP数据包。
  • 网卡分段: 操作系统将这个大数据包交给网卡,由网卡根据MTU(最大传输单元)的大小,将大数据包分割成多个符合网络链路要求的小数据包。
  • 数据发送: 网卡将分割后的数据包逐一发送到网络中。
  • TSO(TCP Segmentation Offload):专门针对TCP协议的大数据包分段。
  • GSO(Generic Segmentation Offload):通用分段卸载,不仅支持TCP,还支持其他协议(如UDP)的大数据包分段。

4: CDN #

详见 [[CDN-Content Delivery Network]]

  1. 静态资源使用CDN(Content Delivery Network)

5: 负载均衡 #

主要基于 Nginx 代理服务器

  1. 选择合适的算法:轮询、加权轮询、最小连接数、最少响应时间、IP哈希、一致性哈希等
  2. 会话保持:基于Cookie的会话保持
  3. 将SSL处理卸载到负载均衡器上: 减少后端服务器的SSL处理负担,提高性能。
  4. worker_processes 一般设置为CPU核数的倍数
  5. worker_connections 设置每个 worker 进程可以同时处理的最大连接数
  6. worker_rlimit_nofile 设置每个 worker 进程可以打开的文件描述符数
  7. 使用共享内存缓存静态文件,减少磁盘I/O
  8. gzip
  9. keepalive
  10. tcp_nopush 减少网络包的发送频率,提高网络传输效率

6: 服务端优化 #

  1. 数据库优化:索引、优化SQL语句、使用连接池、读写分离、分库分表
  2. 缓存:使用 RedisMemcached 缓存中间件,缓存热点数据
  3. 代码优化:算法优化、模块化设计、异步处理、消息队列
  4. 硬件优化:选择合适的服务器配置,适当升级硬件配置
  5. 操作系统优化:自定义内核,关闭不必要的服务
  6. JVM优化:调整对内存大小、垃圾回收等
  7. Web服务器优化:Nginx
  8. 使用服务端渲染(SSR)
  9. 避免重定向
  10. 优化模板渲染逻辑

7: HTTP协议 #

  1. 优先使用 HTTP/3.0、次之 HTTP/2.0,兜底 HTTP/1.1
  2. 使用HTTP/1.1,需要减少 HTTP 请求数量(浏览器限制单域名最大连接数为 6 ~ 8)
  3. 优化Cookie:减少Cookie的大小和数量
  4. HTTP/1.x 开启 Keep-Alive: connection
  5. 资源暗示

HTTP资源暗示是资源暗示的一部分,其可以用来深入优化HTTP的使用。每个暗示使用link HTTP首部或者HTML中的<link>标签来实现。HTTP资源暗示已经存在相当长的时间了,但是最近才被认可、支持。

8: 资源优化 #

  • 资源数量
  • 资源大小(最小化代码)

8.1 资源数量 #

  1. 懒加载图片:图片、分页路由的资源
  2. 精灵图:多个小图标合并成一张图片
  3. 代码分离:过大的资源可以拆分多个Chunk,splitChunks
  4. 不常变更的资源,可以独立build一个chunk

8.2 资源大小 #

  1. Tree Shaking: usedExports, sideEffects, purgecss-webpack-plugin
  2. 代码压缩:JS、CSS、Font混淆压缩;fontmin-webpack font-spider
  3. 图片压缩:imagemin, tinypng.com ;调整图片大小,降低图片质量;使用 CSS3 效果代替图片
  4. 服务器开启 GzipBrotli 算法压缩资源文件
  5. 选择合适的图片格式:优先WebP、AVIF
  6. 避免引入过多的字体
  7. 不发送不需要的内容

JS压缩

  1. UglifyJS
  2. Terser

CSS压缩

  1. CSSNano: CSSNano是一个基于PostCSS的CSS压缩工具,能够移除不必要的空格、注释等。
  2. CleanCSS: CleanCSS是一个免费的CSS精简压缩工具,通过这个在线工具,可以将CSS文件压缩、优化更精简

Reference #