从输入 URL 到看到网页
从输入 URL 到看到网页
完整流程
输入 URL
↓
1. DNS 解析
↓
2. 建立 TCP 连接
↓
3. 发送 HTTP 请求
↓
4. 服务器返回响应
↓
5. 浏览器解析 HTML
↓
6. 构建 DOM 树
↓
7. 构建 CSSOM 树
↓
8. 构建渲染树
↓
9. 布局(Layout)
↓
10. 绘制(Paint)
↓
用户看到页面
1. DNS 解析
把域名翻译成 IP 地址。
输入:www.example.com
↓
查本地缓存(浏览器缓存 → 系统缓存 → hosts 文件)
↓ 没有缓存
查 DNS 服务器
↓
返回 IP:93.184.216.34
2. 建立 TCP 连接(三次握手)
找到服务器 IP 后,建立可靠连接:
客户端 → SYN(我想连接你)→ 服务器
客户端 ← SYN+ACK(好的,我准备好了)← 服务器
客户端 → ACK(收到,开始通信)→ 服务器
如果是 HTTPS,还需要额外的 TLS 握手(协商加密方式、交换证书)。
3. 发送 HTTP 请求
TCP 连接建立后,浏览器发送请求:
GET / HTTP/1.1
Host: www.example.com
User-Agent: Chrome/...
Accept: text/html
Cookie: ...
4. 服务器返回响应
服务器处理请求,返回:
HTTP/1.1 200 OK
Content-Type: text/html
Cache-Control: max-age=3600
<!DOCTYPE html>
<html>...
5. 浏览器解析 HTML,构建 DOM 树
浏览器从上到下解析 HTML:
HTML 字节流
↓ 解码
字符串
↓ 词法分析(Tokenize)
Token(标签、文本)
↓ 语法分析
DOM 树
<html>
<body>
<div>
<p>Hello</p>
</div>
</body>
</html>
6. 遇到资源怎么处理
解析 HTML 过程中遇到各种资源:
- CSS:下载并解析,构建 CSSOM,不阻塞 HTML 解析,但阻塞渲染
- JS(没有 async/defer):立刻暂停 HTML 解析,下载并执行完再继续
- JS(async):异步下载,下载完立刻执行
- JS(defer):异步下载,HTML 解析完再执行
- 图片:异步下载,不阻塞解析
7. 构建 CSSOM 树
CSS 文件
↓ 解析
CSSOM 树(每个节点包含样式信息)
8. 构建渲染树(Render Tree)
DOM 树 + CSSOM 树 = 渲染树
DOM 树 CSSOM 树
+ +
↘ ↙
渲染树
(只包含可见节点,display:none 的不在渲染树里)
9. 布局(Layout / Reflow)
计算每个节点的位置和大小:
渲染树
↓
计算每个元素的:
- 坐标(x, y)
- 尺寸(width, height)
- 相对/绝对位置
10. 绘制(Paint)
把布局结果画到屏幕上:
布局信息
↓
绘制文字、颜色、边框、阴影...
↓
合成图层(Composite)
↓
显示到屏幕
关键性能节点
| 节点 | 说明 |
|---|---|
| TTFB(首字节时间) | 从请求到收到第一个字节 |
| FCP(首次内容绘制) | 页面第一个内容出现 |
| LCP(最大内容绘制) | 最大元素渲染完成 |
| TTI(可交互时间) | 页面可以响应用户操作 |
优化方向
- DNS 预解析:
<link rel="dns-prefetch" href="//cdn.example.com"> - 减少请求体积:代码压缩、图片优化
- 缓存:静态资源加 hash + 长期缓存
- JS 不阻塞渲染:script 加
defer - CSS 不阻塞渲染:关键 CSS 内联,非关键 CSS 异步加载
- SSR:服务端直接返回完整 HTML,减少白屏时间
