1. DNS 域名解析
- 递归查询(浏览器 → 本地 DNS)
- 浏览器缓存 → 系统缓存(hosts)→ 路由器缓存 → ISP DNS 缓存
- 迭代查询(本地 DNS → 根域/顶级域/权威 DNS)
- 根 DNS → 返回顶级域(如
.com)DNS - 顶级域 DNS → 返回权威 DNS(如
google.com) - 权威 DNS → 返回目标主机 IP
- 根 DNS → 返回顶级域(如
- 优化:多级缓存(浏览器、OS、路由器、ISP、各级 DNS)
2. 建立 TCP 连接(三次握手)
- 客户端 → 发送
SYN(同步序列号) - 服务端 → 回复
SYN + ACK - 客户端 → 发送
ACK,连接建立
HTTPS 额外步骤:
- TLS 握手:协商加密算法、验证证书、交换密钥(非对称加密 → 对称加密)
3. 发送 HTTP 请求 & 服务器处理
- 请求:浏览器发送 HTTP 请求(含请求头、缓存标识如
If-None-Match) - 服务器:检查缓存 → 返回
304(未修改)或200+ 新资源
4. 关闭 TCP 连接(四次挥手)
- 客户端 →
FIN - 服务端 →
ACK - 服务端 →
FIN - 客户端 →
ACK(等待 2MSL 后关闭)
5. 浏览器渲染流程
- 构建 DOM 树
- 字节 → 字符 → Tokens → Nodes → DOM 树(建立父子关系)
- 样式计算(CSSOM)
- 解析 CSS(内联/外联/嵌入样式)→ 计算每个节点的最终样式
- 布局(Layout)
- 排除非可视化节点(如
<script>、display: none)→ 生成布局树(含位置/尺寸)
- 排除非可视化节点(如
- 分层(Layer)
- 对复杂效果(3D 变换、
z-index)创建独立图层
- 对复杂效果(3D 变换、
- 栅格化(Raster)
- 将图层分块 → 转换为位图(优先处理视口内内容)
- 合成与显示
- 合成线程提交位图 → 浏览器进程绘制到屏幕
关键点总结
| 阶段 | 核心步骤 | 优化/注意 |
|---|---|---|
| DNS | 递归 + 迭代查询 | 多级缓存、负载均衡 |
| TCP | 三次握手 + TLS(HTTPS) | 减少握手延迟(如 TCP Fast Open) |
| HTTP | 请求/响应 + 缓存验证 | 强缓存/协商缓存(Cache-Control/ETag) |
| 渲染 | DOM → CSSOM → 布局 → 绘制 | 避免回流(重排)和重绘 |
常见面试问题
- 为什么需要三次握手?
- 防止历史重复连接初始化导致的资源浪费。
- HTTPS 握手比 HTTP 慢在哪里?
- 多出 TLS 握手(2 RTT)和加密计算开销。
- 如何优化渲染性能?
- 减少 DOM 深度、使用
transform替代top/left(避免回流)、懒加载。
- 减少 DOM 深度、使用
- DNS 查询为什么用 UDP?
- 速度快(无连接),适合小数据包(通常 < 512B)。