HTTP 基于 TCP,TCP 面向连接。建立连接才能传输内容,这通常在日常开发中不易察觉,但对新用户场景、着陆页等有较大影响。图示中,TCP部分为常说的建连时间,包括SSL握手时间,后续提及的建连时间也指此段。RTT(往返时延)是发送端发送数据至接收端确认 ACK 的时间,一般由物理距离和网络路径决定。一个 RTT 通常接近 Ping 测试中显示的时间。TCP 连接建立通过三次握手完成,耗时一个 RTT。若不考虑 SSL 握手时间,建连仅影响 HTTP 协议。HTTPS 需额外考虑 SSL 握手时间,后续文章会详述。 动手实验:使用 WireShark 抓取一次 HTTP 请求,观察建连过程。可以看到,发起 seq 到收到 ACK(经过 1 RTT)后,客户端直接发送 GET 请求。优化建连时间,测试页面加载性能。页面 JavaScript 文件及后续 fetch 请求的 DNS + Connect + SSL 时间较长,因域名不同需重新解析,导致额外建连(包括 SSL 握手),fetch 请求耗时约 500ms。 为解决此问题,Chrome 引入 Preconnect,允许提前建立连接。在页面中加入相关代码,告知浏览器提前建立连接。这样,在 JS 加载后,fetch 请求开始前,连接已建立,提前进行了 DNS 解析。连接复用,不使用 Preconnect 时,同一连接可减少额外连接次数。域名收拢,HTTP 1 时代优化分散域名以并行加载,HTTP 2 普及后,连接复用减少额外连接成本。尽可能将域名收拢,减少建连耗时。IP 收拢,同一 IP 时,可复用连接,尽管需额外解析 DNS。全站加速技术可帮助减少连接建立。 理解连接建立为何耗时,三次握手确保数据传输的顺序和完整性。TCP 包序号(Sequence Number)在接收端重组传输包内容,确认不丢包。握手同步 ISN(Initial Sequence Number),避免序列冲突。不能使用固定值,避免相邻 TCP 连接间的干扰。TCP Fast Open 在建立连接时预发数据,减少不稳定连接时的重连耗时,但支持不普遍,受限于操作系统实现。 QUIC 和 HTTP3 解决了部分建连问题,但本文不展开。总结,HTTP 基于 TCP,TCP 连接建立通过三次握手,耗时一个 RTT。连接复用、域名与 IP 收拢可减少建连耗时。使用 Preconnect 提前建立连接,确保正确复用,优化即将发起的请求和 redirect。深入理解 TCP 和连接建立原理,有助于优化网页性能。