计算机网络:浏览器输入一个网址,回车后发生了什么?
结论:URL 解析 → 查缓存 → DNS 解析 → TCP 三次握手 → TLS 握手(HTTPS 才有)→ 发送 HTTP 请求 → 服务端处理并响应 → 浏览器解析渲染 → 加载子资源。整条链路上每一环都可能成为瓶颈,所以排查也按这个顺序分段计时。
1. 全链路
地址栏回车
│ ① 解析 URL:scheme / host / port / path / query
│ ② 查缓存:浏览器缓存 → HSTS 列表 → Service Worker
▼
DNS 解析:浏览器 DNS 缓存 → 系统 DNS 缓存 / hosts → 本地 DNS → 根 / 顶级 / 权威
▼
TCP 三次握手(SYN → SYN+ACK → ACK),得到一条连接
▼
TLS 握手(HTTPS):ClientHello → 证书校验 → 密钥协商 → Finished
▼
HTTP 请求:GET / HTTP/1.1 + Host + Cookie + User-Agent ...
▼
服务端:负载均衡 → 应用 → 缓存 / 数据库 → 响应
▼
浏览器:解析 HTML → 构建 DOM / CSSOM → 布局 → 绘制 → 合成
▼
加载子资源:CSS / JS / 图片 / 字体(复用连接或新建连接)
2. 每段的瓶颈与优化
| 阶段 | 主要耗时 | 优化手段 |
|---|---|---|
| DNS | 递归查询 RTT、缓存未命中 | 减少域名数量、调大 TTL、HTTPDNS |
| TCP | 1 个 RTT,外加慢启动 | 连接复用、长连接、就近接入 |
| TLS | 1~2 个 RTT | TLS 1.3、会话复用、OCSP stapling |
| 请求/响应 | 服务端处理时间、TTFB | 缓存、索引、异步化、CDN |
| 渲染 | 关键渲染路径、JS 阻塞 | 内联关键 CSS、defer / async、懒加载 |
3. 用一条命令把时间拆开
# -w 的格式串要写成一行,别在单引号里用反斜杠折行,curl 不认这种续行
curl -o /dev/null -s -w 'dns=%{time_namelookup}s tcp=%{time_connect}s tls=%{time_appconnect}s ttfb=%{time_starttransfer}s total=%{time_total}s\n' https://example.com/
读法:
time_namelookup是 DNS 完成的时刻,它本身就是 DNS 耗时。time_connect减time_namelookup是 TCP 握手耗时。time_appconnect减time_connect是 TLS 握手耗时。time_starttransfer减time_appconnect是服务端处理 + 首字节(TTFB)。time_total是总耗时。
DNS 单独看:
dig +trace example.com # 从根开始逐级观察委派
dig @8.8.8.8 example.com +short # 指定解析器,对比本机是否有缓存污染
4. 渲染阶段在做什么
HTML --解析--> DOM
CSS --解析--> CSSOM
DOM + CSSOM --合成--> 渲染树 --布局(Layout)--> 绘制(Paint)--> 合成(Composite)
<script>默认阻塞 HTML 解析;defer等文档解析完再按序执行;async下载完立即执行,顺序不定。- CSS 阻塞渲染:样式没算好,浏览器不敢画首屏。
- 首屏优化就是压缩这条关键路径:内联首屏 CSS、减少阻塞脚本、图片写死宽高避免布局抖动。
5. 常见追问
Q:第二次访问为什么快很多?
DNS 有缓存、TCP 连接可复用、TLS 会话可恢复、静态资源命中强缓存(直接不发请求)或协商缓存(返回 304)。
如果第二次仍然慢,先看入口 HTML 是不是被设成了 no-store。
Q:输入的是关键词而不是网址呢? 浏览器先做启发式判断:含空格、含中文、没有点号,一般交给默认搜索引擎; 含点号且能解析的,按域名处理。地址栏"搜索还是导航"是浏览器策略,不是协议规定。
Q:HTTP/2 之后还需要域名分片吗? 不需要。HTTP/2 多路复用把并发压到一条连接上,域名分片反而多付 DNS 与 TCP/TLS 的开销。 HTTP/3 基于 QUIC,进一步消除 TCP 层的队头阻塞。
Q:域名解析失败会怎样?
DNS 返回 NXDOMAIN,浏览器显示"找不到服务器";解析成功但连不上,则表现为连接超时或拒绝。
排查顺序:先 dig 确认解析,再 curl -v 确认连接,最后才怀疑应用。
Q:301 和 302 对这次访问有什么影响? 301 永久重定向会被浏览器长期缓存,换域名后想回滚很麻烦;302 临时重定向默认不缓存(除非显式带头)。 HTTPS 跳转用 301 没问题,灰度或临时迁移要用 302 / 307。
Q:为什么 HTTPS 首次访问明显慢? 多出 TLS 握手(TLS 1.2 是 2 个 RTT),还要下载并校验证书链。 启用 TLS 1.3、会话票据与 OCSP stapling 后,二次访问可以接近纯 TCP 的成本。
Q:CDN 在这条链路的哪一环? 在 DNS 与 TCP 之间:权威 DNS 返回 CNAME,调度系统给出就近边缘节点 IP,后面的 TCP / TLS / HTTP 都连到边缘。 所以 CDN 同时优化了 DNS 之后的 RTT 与服务端 TTFB。
小结
把一次访问拆成"解析 → DNS → 连接 → 加密 → 请求 → 响应 → 渲染"七段,每段都有明确的观测指标:
time_namelookup、time_connect、time_appconnect、time_starttransfer、time_total。
面试时按这个顺序讲,既不会漏,也能自然带出缓存、连接复用、CDN、关键渲染路径这些延伸点。