阅读视图

发现新文章,点击刷新页面。

TCP/IP 与前端性能:从数据包到首次渲染的底层逻辑

TCP/IP 与前端性能:从数据包到首次渲染的底层逻辑

这是“从 URL 到页面展示”系列第三篇。前面两篇我们聊完了浏览器导航DNS 与传输层细节,今天我们钻进 TCP/IP 协议栈的核心,看看一个数据包究竟怎么跑完全程,以及它为什么直接影响前端最关心的性能指标 FP(首次渲染时间)


一、前端性能的起点:FP 与 TTFB

面试官问“怎么优化页面加载速度”,你可以先说两个关键时间点:

  • TTFB(Time To First Byte):从发起请求到收到服务器第一个字节的耗时 = DNS 解析 + TCP/TLS 连接 + 服务器处理 + 响应传输的第一个字节到达。
  • FP(First Paint):从页面加载到浏览器首次绘制出像素的耗时 = TTFB + HTML 解析 + CSSOM 构建 + 渲染树构建 + 布局 + 首次绘制。

从这个公式可以看出:TTFB 里有一大块时间花在网络传输上,而网络传输的根基就是 TCP/IP。前端做性能优化,不能只盯着 JS 和 CSS,还得懂底层。


二、数据包的旅程:互联网的“快递系统”

互联网本质是一套理念和协议组成的体系架构,数据不是一整块丢进网线的,而是拆成一个一个数据包传输。

为什么拆包?

  • 单个文件可能几十 MB,一次性发送会长时间占用整条链路,其它请求就得排队。
  • 拆成小包后,可以利用带宽并发传输,提升传输效率和容错率。某个包丢了,只需要重发这一个,不用重发全部。

这些数据包最终会变成二进制数据帧,在物理介质上流动。


三、IP 层:只负责“送到”,不负责“送到位”

IP(Internet Protocol)是网络层的协议,职责非常单纯:根据 IP 地址,把数据包从源主机送到目标主机

它做的是“尽力而为”的服务:

  • 可能丢包
  • 可能出错
  • 可能不按顺序到达
  • 不提供任何纠正机制

所以 IP 本身是一个“不可靠”的协议。前端请求的 HTML 文件结构严密,一个字节错位都可能导致渲染异常,怎么办?

答案就在传输层。


四、UDP vs TCP:两种“快递模式”

传输层运行在 IP 之上,负责将数据包交付到目标主机上的具体应用(通过端口号)。主要有两位选手:

UDP(User Datagram Protocol):只管快

  • 不建立连接,直接发包。
  • 不保证顺序,不重传丢失的包。
  • 头部开销小,速度快。

适用场景:对实时性要求极高、能容忍少量数据丢失的音视频直播、视频通话、在线游戏。

TCP(Transmission Control Protocol):保证到位

对于 HTML、CSS、JS、图片这类 Web 资源,哪怕一个包出错都可能导致页面渲染异常。TCP 专门解决两个核心问题:

问题 TCP 的解法
数据包在传输过程中丢失 超时重传机制 — 每发一个包,启动一个计时器,过期未收到确认就重发
数据包到达接收端顺序错乱 序号机制 — 每个包都带有序号,接收端按序号重新组装

因为要保证可靠性,TCP 比 UDP 慢 —— 但这恰恰是 Web 页面需要的可靠传输


五、三次握手:建立可靠连接

在真正发送 HTTP 请求之前,TCP 需要通过三次握手建立连接。核心目的:同步初始序号,验证双方收发能力

简化过程:

  1. 客户端 → 服务器SYN,带上初始序号 J
    “我想和你建立连接,我发送的包从 J 开始编号,你听得到吗?”

  2. 服务器 → 客户端SYN + ACK,确认号 J+1,同时带上自己的初始序号 K
    “听到了,你下一个从 J+1 开始发。我也想和你建立连接,我的包从 K 开始编号,你听得到吗?”

  3. 客户端 → 服务器ACK,确认号 K+1
    “听到了,你下一个从 K+1 开始发。咱们可以正式开始传数据了。”

高频追问:为什么是三次,不是两次或四次?

  • 两次不够:服务器无法确认客户端能收到自己的消息(无法确认客户端有接收能力)。
  • 四次没必要:第二次握手时,服务器把 “响应客户端的 SYN”“发出自己的 SYN” 合并成一条消息,效率最大化。
    原则是:每一方的发送和接收能力都需要两次验证,但因为服务器把两个动作合并了,总共只需三次。

过程图

image.png

六、四次挥手:优雅地断开连接

数据传输完毕(比如 HTML 下载完成、图片加载结束),需要断开 TCP 连接释放资源。这个过程需要四次挥手

  1. A → BFIN,带上序号 M
    “我没有数据要发了,想断开连接。”

  2. B → AACK,确认号 M+1
    “知道你没数据了,但我可能还有数据没发完,你再等等。”

  3. B → AFIN,带上序号 N
    “我的数据也发完了,可以断开了。”

  4. A → BACK,确认号 N+1
    “好的,我知道你也没数据了。再见。”

为什么比握手多一次?因为 TCP 是全双工的,双方都可以独立发送和接收数据。一端说“我发完了”,另一端可能还有数据要传,所以 FIN 和 ACK 不能合并,必须分开发送,正好四次。

过程图

image.png


七、回到前端:这些对性能优化意味着什么?

理解了 TCP,就能看懂很多性能优化的底层逻辑:

优化手段 背后的 TCP 原理
减少 HTTP 请求数(雪碧图、合并文件) 每个 TCP 连接都有三次握手开销,请求数越少,握手成本越低
使用 HTTP/2 多路复用 单个 TCP 连接上并发传输多个请求和响应,避免重复握手
启用 TCP Fast Open 在握手阶段就开始传数据,将握手和数据传输部分重叠,降低 TTFB
使用 CDN 缩短物理距离 → 减少 RTT(往返时延)→ 丢包概率降低 → 重传少 → 更快
资源预连接(preconnect) 提前完成 DNS + TCP + TLS 握手,请求时直接使用已建立的连接

八、总结:一条链路串起知识体系

至此,我们串联起了整个前端性能链条的网络部分:

DNS 解析(IP 找到主机)
  → TCP 三次握手(建立可靠连接)
  → TLS 握手(加密安全)
  → HTTP 请求/响应(应用层数据)
  → TCP 四次挥手(断开连接)

每一个环节的耗时,都叠加进了 TTFB,进而影响 FP。下次面试问到性能优化,你完全可以从这个底层视角切入,展示你对网络协议栈的真懂,而不是只背“减少请求数”的表面答案。


从 URL 到页面展示,还有哪些你忽略的底层细节?(DNS 与传输篇)

从 URL 到页面展示,还有哪些你忽略的底层细节?(DNS 与传输篇)

上一篇文章我们用「浏览器多进程架构」为主线,拆解了从输入 URL 到页面渲染的完整导航过程。很多读者反馈:DNS 和传输层部分还值得再挖深一点 —— 面试时能不能多讲一些「IP 地址背后的事」?数据到底是怎么从服务器跑到浏览器的?

今天我们就顺着这条链路,把 DNS 的兜底逻辑负载均衡OSI 模型下的数据封包一次讲透,让你在面试中再往底层迈一步。


一、DNS 返回的 IP,并不是最终服务器的 IP

很多人以为 DNS 解析后直接拿到的是真实 Web 服务器的 IP,其实不是。

你可以亲自在 Chrome 地址栏输入 chrome://net-internals/#dns,就能看到浏览器缓存的 DNS 记录。查询一个大型网站,返回的经常是一个 IP 数组(多个地址),而不是单个 IP。

这就是分布式服务器集群所带来的现象。真正和浏览器通信的通常是一台 反向代理服务器(比如 Nginx),它充当“媒婆”的角色:

  • 请求先到这台 Nginx 代理
  • 代理背后有成百上千台真实业务服务器
  • 代理根据负载均衡策略,选择一台把请求转发过去

负载均衡怎么选服务器?

常见的策略有:

  • 轮询:按顺序一台一台分配
  • 加权轮询:配置高的机器多承担一些请求
  • 最少连接数:谁当前任务少就发给谁
  • IP 哈希:让同一用户的请求落到同一台服务器(便于 session 保持)

这样一来,即使某台服务器宕机,代理也能把流量导到健康节点,用户几乎无感知。


二、离你最近的 IP:CDN 的地域性调度

DNS 解析还有一个高级技能:根据你的地理位置,返回离你最近的节点 IP

很多大厂在全国(甚至全球)部署机房,DNS 解析服务会通过用户的 Local DNS 出口 IP 判断你的城市,然后返回附近机房的 Nginx 代理 IP。这就是 CDN 就近接入的底层逻辑。

比如在北京访问 douyin.com,DNS 可能解析到北京的边缘节点;到了上海出差,解析结果会变成上海的节点。不仅降低了延迟,也分散了源站压力。

小技巧:你可以用 nslookupping 测试域名在不同网络下的 IP,能看到 CDN 调度的效果。


三、本地 DNS 的“后门”:hosts 文件

在 DNS 查询链路中,有一个优先级很高却常被开发者忽略的环节:操作系统 hosts 文件

Windows 路径:

C:\Windows\System32\drivers\etc\hosts

macOS / Linux 路径:

/etc/hosts

它可以手动定义域名到 IP 的映射,比如:

127.0.0.1  douyin.com

这样访问 douyin.com 时,浏览器就直接走本地回环地址,完全跳过 DNS 解析

实际开发中的妙用

  • 本地开发时,将测试域名指向 127.0.0.1,就能用真实域名测试 cookie、token 等域名相关逻辑。
  • 线上故障应急时,有时会临时修改 hosts 跳过故障 DNS 或直奔某台服务器。

注意,localhost 这类特殊域名甚至不需解析,操作系统就直接识别成环回地址。


四、数据如何上路:OSI 七层模型形象理解

DNS 拿到 IP 之后,浏览器开始和服务器建立连接,真正传输数据。
这就进入到了经典的 OSI 七层模型(实际互联网更多用 TCP/IP 四层),从下往上看数据的变化:

  1. 物理层
    网线、光纤、无线电波。传输的最底层是 0 和 1 的电信号或光信号。

  2. 数据链路层
    数据被加上 MAC 地址(每台上网设备的唯一硬件标识),组成数据帧。

    目标 MAC + 源 MAC + 数据
    
  3. 网络层
    加上 IP 地址,让数据能够跨网络到达目标主机。

    目标 IP + 源 IP + MAC + 数据
    
  4. 传输层
    再加上 TCP 或 UDP 协议头。TCP 头部包含序号、确认号、窗口大小等,保证可靠性。

    TCP 头(序号…)+ IP + MAC + 数据
    

这就像寄快递:

  • 物理层是公路/飞机
  • 链路层是小区收发室(MAC)
  • 网络层是城市和街道(IP)
  • 传输层是快递公司的签收规则(保证不丢件、不乱序)

五、TCP:可靠传输的规矩

HTTP 协议基于 TCP,而 TCP 为了保证数据完整有序,制定了一套规矩:

1. 拆包与并发传输

服务器要返回一个 HTML 文件,可能几十 KB 甚至几百 KB。TCP 不会一次性全部扔到网上,而会切分成固定大小(MSS)的数据包,分批次、多通道并发发送。

这样即使某个包卡住了,其他包也能继续前进,提高效率。

2. 序号与排序

每个包在 TCP 头部都带着序号,接收端按序号重新拼装数据。
即使包到达的顺序是乱的(因为网络路由不同),也能重新排好。

3. 丢包重发

如果发送方一段时间没收到某个包的确认(ACK),就认为丢包,触发自动重传。这就是 TCP 可靠性的保障。

对比 UDP:UDP 不建立连接、不保证顺序、不重传,但速度快,适合直播、视频会议等对实时性要求高的场景。

4. 三次握手本质

我们在上一篇文章提过三次握手,其实它的核心就是同步双方的初始序号,确认彼此收发能力正常。只有握手完成后,浏览器才会发送真正的 HTTP 请求。


六、落地到面试:你能这样说

当面试官问起“DNS 过程中做了什么”,你可以这样组织语言:

  1. 浏览器先查本地缓存(含 chrome://net-internals/#dns 记录)和操作系统 hosts 文件。
  2. 没有命中,则逐级向上递归查询,直到拿到 IP(很可能是一个反向代理 IP)。
  3. 这个 IP 背后通常是 Nginx 等代理,代理根据负载均衡策略将请求转发到内部某台真实服务器。
  4. 同时 CDN 会通过 DNS 智能解析,返回离用户最近的边缘节点 IP。

问到数据传输,可以补充:

  • 物理层、链路层、网络层、传输层的逐层封包过程
  • TCP 通过拆包、序号、重传来保证可靠性,而 UDP 牺牲可靠性换取速度
  • 三次握手是为了同步序号、验证双方收发能力

这样,不仅讲清了前端视角的请求全过程,还向下扎到了网络架构和传输原理,能充分展示你的计算机基础。


掌握这些细节,你再回答那道经典面试题时,就不再是“表面流程复读机”,而是一个能讲出“为什么”和“底层发生了什么”的开发者。下一期我们可以继续聊聊 HTTPS 的 TLS 握手,敬请期待。

❌