1. 输入URL → 2. DNS解析 → 3. TCP握手 → 4. TLS握手 →
5. HTTP请求 → 6. 服务器处理 → 7. 响应返回 →
8. 解析HTML → 9. 构建DOM/CSSOM → 10. 渲染树 →
11. 布局 → 12. 绘制 → 13. 交互
1. 输入网址并解析
- 用户输入:在浏览器地址栏输入URL(如
https://www.example.com),浏览器会检查输入的内容是否是有效的URL或搜索关键词。
- URL解析:浏览器解析URL的协议(
https)、域名(www.example.com)、端口(默认443)、路径(/)等。
2. DNS 域名解析
- 浏览器缓存:检查本地缓存是否有域名对应的IP地址。
- 系统缓存:若浏览器无缓存,检查操作系统缓存(如Windows的
hosts文件)。
- 路由器缓存:查询本地路由器缓存。
- ISP DNS服务器:若以上均未命中,向ISP(互联网服务提供商)的DNS服务器发起递归查询。
- 递归查询:
- 根DNS服务器 → 顶级域服务器(如
.com) → 权威DNS服务器(如example.com) → 返回IP地址。
- DNS响应:最终获得域名对应的IP地址(如
93.184.216.34)。
+
| DNS查询层级 |
+
| 根DNS | 顶级域DNS | 权威DNS |
| (.) | (.com) | (example.com) |
+
| | |
| 1. 查询".com在哪?" | |
+
| |
| 2. 查询"example.com在哪?" |
+
|
| 3. 返回IP地址
+
|
v
+
| 93.184.216.34 |
| (example.com IP)|
+
3. 建立TCP连接(三次握手)
- SYN:客户端发送SYN包(同步序列编号)到服务器,进入
SYN_SENT状态。
- SYN-ACK:服务器收到SYN后返回SYN+ACK包,进入
SYN_RECEIVED状态。
- ACK:客户端发送ACK包确认,双方进入
ESTABLISHED状态,完成三次握手。
- HTTPS额外步骤:若是HTTPS,还需进行TLS握手(协商加密算法、交换密钥等)。
建立TCP连接(三次握手)
客户端 服务器
|
|<
|
TLS握手(HTTPS安全连接)
1. ClientHello → 支持的加密套件(如TLS_ECDHE_RSA)
2. ServerHello ← 选定套件 + 证书
3. 证书验证 → 生成会话密钥
4. 加密通信开始
4. 发送HTTP请求
- 请求报文:浏览器构造HTTP请求,包含:
- 请求行(如
GET / HTTP/1.1)
- 请求头(如
Host: www.example.com、User-Agent、Accept等)
- 请求体(GET请求通常为空,POST可能有数据)。
- 发送请求:通过TCP连接发送到服务器。
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html, */*
5. 服务器处理请求
- Web服务器(如Nginx/Apache)接收请求,根据路径路由到对应的处理程序。
- 后端处理:动态内容(如PHP/Node.js)可能查询数据库,生成HTML。
- 响应生成:服务器返回HTTP响应,包含:
- 状态行(如
HTTP/1.1 200 OK)
- 响应头(如
Content-Type: text/html)
- 响应体(HTML内容)。
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
<!DOCTYPE html>
<html>...</html>
6. 浏览器解析与渲染
- 解析HTML:
- 构建DOM树:将HTML标签转换为树状结构。
- 遇到
<link>/<script>/<img>等标签时,加载外部资源(CSS/JS/图片)。
| 标签类型 | 阻塞DOM解析 | 阻塞页面渲染 | 加载方式 | 优化建议 |
|---|
<link>(CSS) | 否 | 是 | 同步加载 | 内联关键CSS |
<script> | 是(默认) | 是 | 同步加载 | 使用async/defer |
<img> | 否 | 否 | 异步加载 | 懒加载 |
<html>
<head>...</head>
<body>
<div>Hello World</div>
</body>
</html>
- 解析CSS:
div { color: red; }
- 合并DOM与CSSOM:
- 生成渲染树(Render Tree),排除不可见元素(如
display:none)。
- 布局(Layout):
┌─────────────┐
│ DIV │
│ (red text) │
└─────────────┘
- 绘制(Paint):
- 执行JavaScript:
- 遇到
<script>会阻塞DOM解析,除非标记为async或defer。
+----------------+ +----------------+ +-----------------+
| HTML | | CSS | | Render Tree |
| (DOM树) | | (CSSOM树) | | (渲染树) |
+-------+--------+ +-------+--------+ +--------+--------+
| | |
| 1. 解析HTML标签 | 2. 解析CSS规则 | 3. 合并DOM+CSSOM
| 生成DOM树 | 生成CSSOM树 | 排除不可见元素
| | |
v v v
+----------------+ +----------------+ +-----------------+
| | | | | div (visible) |
| <html> | | body {margin:0}| | ┌────────────┐ |
| <head> | | div {color:red}| | │Hello World │ |
| <body> | | | | └────────────┘ |
| <div>Hello | +----------------+ +-----------------+
| World</div> | |
| </body> | |
| </html> | |
+----------------+ |
v
+-----------------------------+ +------------------------------+
| Layout | | Paint |
| (布局/重排) | | (绘制/重绘) |
| 计算元素大小和位置 | | 将布局转换为屏幕像素 |
| ┌──────────────────┐ | | +---------------------+ |
| │div: width=200px │ | | │ 渲染像素到屏幕 │ |
| │ height=100px │ | | │ │ |
| │ x=50, y=30 │ | | +---------------------+ |
| └──────────────────┘ | | |
+-----------------------------+ +------------------------------+
7. 加载动态资源
- 异步请求:页面可能通过AJAX/Fetch动态加载数据。
- 事件绑定:JavaScript为DOM元素绑定交互事件。
关键点总结
- DNS解析:将域名转换为IP地址。
- TCP连接:通过三次握手建立可靠传输。
- HTTP请求/响应:客户端与服务器通信。
- 渲染引擎工作:解析→渲染→交互。
示意图(简化版)
用户输入URL → DNS解析 → TCP握手 → HTTPS握手 → HTTP请求 → 服务器处理 → 返回响应 → 浏览器解析 → 渲染页面