- Published on
从地址栏到页面呈现:浏览器到底做了什么?
- Authors

- Name
- Zxu
当我们在浏览器地址栏里输入一个 URL 并按下回车,看似是再普通不过的操作,但背后却启动了一套庞大且精细的协作系统。从 DNS 解析、TCP/TLS 连接,到 HTTP 通信,再到浏览器内部的解析与渲染,每一步都在高速运转,只为在最短时间内把网页稳定、完整地呈现给用户。
1. 浏览器解析 URL
浏览器首先会判断用户输入的是否为合法 URL,并将其拆解成各个组成部分,以便为后续流程做准备。
例如:https://zxuxuuu.cn:443/tags?id=1#info
浏览器会得到:
| 部分 | 含义 |
|---|---|
https | 协议(HTTP / HTTPS) |
zxuxuuu.cn | 域名 |
443 | 端口(HTTPS 默认 443,HTTP 默认 80) |
/tags | 请求路径 |
?id=1 | 查询参数 |
#info | 页面锚点(Hash) |
URL 解析完成后,浏览器就知道应该访问谁、走什么协议、以及要请求什么内容。
2. DNS(Domain Name System 域名系统)解析:寻找真实 IP
解析完URL后,浏览器想要真正的访问到目标服务器,就必须要知道它的真实ip地址。而域名本身是ip地址的映射,便于人们方便记忆的别名。例如 像23.54.135.176这种文本很难记住。因此我们才使用example.com这样的域名来代替。
2.1 浏览器会优先查缓存
当浏览器需要解析域名时,会先从各种缓存中查找,确保能在最短时间拿到ip地址。会按照以下顺序依次查找
- 浏览器缓存 (是否历史曾经访问过此域名并且依旧存在于浏览器缓存中)
- 系统缓存(操作系统层面是否有缓存记录)
- 本地域名解析服务缓存(通常是运营商提供的 DNS)
如果在这些缓存中就能找到 IP,浏览器会直接使用,避免网络查询。
2.2 如果本地 DNS 无法解析,会逐级递归查询
DNS 查询的层级如下:
- 根域名服务器(Root Server) :全球有 13 个标识符(A-M),但通过任播技术实际有数百个物理实例分布在世界各地,确保高可用性。
- 顶级域名服务器(TLD,例如 .com、.cn)
- 权威 DNS 服务器:负责具体域名的最终解析
解析路径示例(以 zxuxuuu.cn 为例):
浏览器 -> 本地DNS -> 根服务器 -> .cn 服务器 -> zxuxuuu.cn 的权威 DNS -> 返回 IP
- 根服务器 不解析域名,它只告诉你应该找哪个顶级域名服务器(例如 .cn)
- 顶级域名服务器告诉你去哪个权威 DNS
- 权威 DNS 才真正返回业务域名的 IP
查询成功后会层层向下返回,并在各层缓存一段时间(TTL)。
2.3 特殊情况:HOSTS 文件
在 DNS 查询之前,操作系统还会读取本地的 hosts 文件。 例如: 127.0.0.1 local.test
如果一个域名在 hosts 里被写死,则 跳过所有 DNS 流程。
2.4 内网域名如何解析?
内网通常会配备公司内部的 DNS 服务器,例如:
service.company.local api.intranet
解析流程一样,只不过本地 DNS 就能直接返回结果,无需触达根服务器。
3. 建立TCP连接(三次握手)
在DNS解析出IP地址后,浏览器还需要和服务器建立连接之后才能发送数据,这就是TCP(Transmission Control Protocol 传输控制协议)连接。 为了建立连接,浏览器使用了三次握手的机制
- 浏览器发送了一个SYN报文,告诉服务器“我想建立连接”
- 服务器收到后回复SYN+ACK,意思是我收到的请求并同意建立连接
- 浏览器收到这个回复后发送一个ACK,确认连接正式建立
| 标志位 | 含义 |
|---|---|
| SYN (Synchronize) | 用来发起连接,告诉对方“我想和你建立一个 TCP 连接,并同步序列号” |
| ACK (Acknowledgment) | 确认收到对方发送的数据包,告诉对方“我收到了你的消息” |
至此,一个可靠的双向通道就建立起来了。
现代浏览器普遍启用了 TCP Fast Open(TFO),在某些情况下允许在握手期间就发送数据,但这需要浏览器和服务器都支持。
4. TLS(Transport Layer Security 传输层安全性协议)/SSL握手(HTTPS)
TLS 握手流程
- 客户端发送 ClientHello 告诉服务器支持的加密算法、版本等信息
- 服务器回复 ServerHello 选择加密算法,发送证书给客户端(证书里有公钥)
- 客户端验证证书 如果合法,生成随机数,加密后发送给服务器
- 双方生成会话密钥 后续数据使用这个对称密钥加密传输
- 握手完成 浏览器和服务器可以安全地交换 HTTP 数据
TLS 完成后,才正式进入安全的 HTTP 请求阶段。
5. 发送 HTTP 请求
浏览器构建 HTTP 报文,包括:
- 请求方法(GET / POST / PUT...)
- 路径和查询参数
- Header(Host、Cookie、Content-Type、Accept、connection、User-Agent…)
- 请求体(POST/PUT)
然后通过已经建立的 TCP/TLS 通道发送给服务器。
6. 服务器处理并返回响应
服务器会:
- 解析请求
- 执行业务逻辑(如查询数据库)
- 生成 HTTP 响应报文(状态码 + Header + Body)
- 返回给浏览器
7. TCP 断开连接(四次挥手)
Connection: keep-alive。- 客户端 -> 服务器:FIN 浏览器告诉服务器:“我已经没有数据要发送了,想关闭连接。”
- 服务器 -> 客户端:ACK 服务器确认收到关闭请求
- 服务器 -> 客户端:FIN 服务器也告诉客户端:“我数据发送完了,可以关闭连接。”
- 客户端 -> 服务器:ACK 浏览器确认服务器 FIN,TCP 连接正式关闭
HTTP/1.1 默认开启长连接,因此不会每次请求后都断开。
HTTP 协议版本差异
| 特性 | HTTP/1.0 | HTTP/1.1 | HTTP/2 |
|---|---|---|---|
| 是否默认开启 Keep-Alive | ❌ | ✅ | ✅ |
| 并发请求能力 | ❌ | ❌(队头阻塞) | ✅ 多路复用) |
| 头部压缩 | ❌ | ❌ | ✅ |
8. 浏览器开始渲染页面
收到 HTML 文本后,浏览器正式进入渲染阶段。
流程如下:
8.1 构建 DOM(Document Object Model)
解析 HTML -> 构建 DOM 树。
8.2 构建 CSSOM(CSS Object Model)
下载 CSS -> 解析 -> 生成 CSSOM。
CSS 文件的下载和解析会阻塞渲染树的生成,因为浏览器需要完整的 CSSOM 才能确定最终的样式表现。
8.3 合并生成渲染树(Render Tree)
DOM + CSSOM -> Render Tree(不包含 display:none 的元素)
8.4 布局(Layout)
计算每个元素的大小与位置(回流)。
8.5 绘制(Paint)
绘制颜色、边框、文字(重绘)。
8.6 合成(Composite)
由合成线程把图层提交给 GPU,最终呈现到屏幕。
9. 渲染过程中你需要了解的关键概念
9.1 重排(Reflow)
当元素的大小、位置、结构发生变化,需要重新计算布局。
例如:
- 改变宽高
- 新增删除 DOM
- 修改字体大小
9.2 重绘(Repaint)
仅视觉发生变化,不影响布局。
例如:
- color
- background-color
10. JS 与渲染的配合机制
10.1 defer / async / preload
| 属性 | HTML 解析阻塞 | 执行时机 | 执行顺序 |
|---|---|---|---|
| 无属性 | ✅ 阻塞 | 立即执行 | 顺序执行 |
| async | ❌ 不阻塞 | 下载完立即执行 | 无序 |
| defer | ❌ 不阻塞 | DOMContentLoaded 前 | 顺序保持 |
| preload | ❌ 不阻塞 | 不自动执行 | 用于性能优化 |
11. JS 事件循环机制(Event Loop)
浏览器会维护:
- 宏任务队列(setTimeout、setInterval、I/O 操作、UI 渲染)
- 微任务队列(Promise.then、queueMicrotask、MutationObserver)
完整的事件循环流程:
- 执行同步的 主线程代码
- 清空微任务队列
- 如有需要,执行渲染更新(requestAnimationFrame)
- 从宏任务队列取一个任务执行
- 重复步骤 2-4
12. 渲染完成
渲染树构建 -> 布局 -> 绘制 -> 合成
最终页面呈现在用户面前。
结语
从地址栏输入 URL 到页面出现在屏幕上,浏览器、网络、操作系统、服务器共同协作完成了多个步骤。这篇文章从网络协议到渲染原理,梳理了整个过程的主干逻辑,希望能帮助你在实际开发中更准确地理解页面加载的每一个环节。