Published on

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

Authors
  • avatar
    Name
    Zxu
    Twitter
💡 前言

当我们在浏览器地址栏里输入一个 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)
💡 Hash Hash部分不会被发送到服务器,只用于客户端页面跳转(如 SPA 路由或锚点定位)。

URL 解析完成后,浏览器就知道应该访问谁、走什么协议、以及要请求什么内容。


2. DNS(Domain Name System 域名系统)解析:寻找真实 IP

解析完URL后,浏览器想要真正的访问到目标服务器,就必须要知道它的真实ip地址。而域名本身是ip地址的映射,便于人们方便记忆的别名。例如 像23.54.135.176这种文本很难记住。因此我们才使用example.com这样的域名来代替。

2.1 浏览器会优先查缓存

当浏览器需要解析域名时,会先从各种缓存中查找,确保能在最短时间拿到ip地址。会按照以下顺序依次查找

  1. 浏览器缓存 (是否历史曾经访问过此域名并且依旧存在于浏览器缓存中)
  2. 系统缓存(操作系统层面是否有缓存记录)
  3. 本地域名解析服务缓存(通常是运营商提供的 DNS)

如果在这些缓存中就能找到 IP,浏览器会直接使用,避免网络查询。


2.2 如果本地 DNS 无法解析,会逐级递归查询

DNS 查询的层级如下:

  1. 根域名服务器(Root Server) :全球有 13 个标识符(A-M),但通过任播技术实际有数百个物理实例分布在世界各地,确保高可用性。
  2. 顶级域名服务器(TLD,例如 .com、.cn)
  3. 权威 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 传输控制协议)连接。 为了建立连接,浏览器使用了三次握手的机制

  1. 浏览器发送了一个SYN报文,告诉服务器“我想建立连接”
  2. 服务器收到后回复SYN+ACK,意思是我收到的请求并同意建立连接
  3. 浏览器收到这个回复后发送一个ACK,确认连接正式建立
标志位含义
SYN (Synchronize)用来发起连接,告诉对方“我想和你建立一个 TCP 连接,并同步序列号”
ACK (Acknowledgment)确认收到对方发送的数据包,告诉对方“我收到了你的消息”

至此,一个可靠的双向通道就建立起来了。

💡 提示:

现代浏览器普遍启用了 TCP Fast Open(TFO),在某些情况下允许在握手期间就发送数据,但这需要浏览器和服务器都支持。


4. TLS(Transport Layer Security 传输层安全性协议)/SSL握手(HTTPS)

💡 提示: TLS 握手发生在 TCP 已经建立之后。

TLS 握手流程

  1. 客户端发送 ClientHello 告诉服务器支持的加密算法、版本等信息
  2. 服务器回复 ServerHello 选择加密算法,发送证书给客户端(证书里有公钥)
  3. 客户端验证证书 如果合法,生成随机数,加密后发送给服务器
  4. 双方生成会话密钥 后续数据使用这个对称密钥加密传输
  5. 握手完成 浏览器和服务器可以安全地交换 HTTP 数据

TLS 完成后,才正式进入安全的 HTTP 请求阶段。


5. 发送 HTTP 请求

浏览器构建 HTTP 报文,包括:

  • 请求方法(GET / POST / PUT...)
  • 路径和查询参数
  • Header(Host、Cookie、Content-Type、Accept、connection、User-Agent…)
  • 请求体(POST/PUT)

然后通过已经建立的 TCP/TLS 通道发送给服务器。


6. 服务器处理并返回响应

服务器会:

  1. 解析请求
  2. 执行业务逻辑(如查询数据库)
  3. 生成 HTTP 响应报文(状态码 + Header + Body)
  4. 返回给浏览器

7. TCP 断开连接(四次挥手)

💡 提示 是否断开连接取决于 HTTP 版本以及是否使用 Connection: keep-alive
  1. 客户端 -> 服务器:FIN 浏览器告诉服务器:“我已经没有数据要发送了,想关闭连接。”
  2. 服务器 -> 客户端:ACK 服务器确认收到关闭请求
  3. 服务器 -> 客户端:FIN 服务器也告诉客户端:“我数据发送完了,可以关闭连接。”
  4. 客户端 -> 服务器:ACK 浏览器确认服务器 FIN,TCP 连接正式关闭

HTTP/1.1 默认开启长连接,因此不会每次请求后都断开。

HTTP 协议版本差异

特性HTTP/1.0HTTP/1.1HTTP/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
💡 提示 重排(Reflow)一定会触发重绘,但重绘不一定触发重排。

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)

完整的事件循环流程:

  1. 执行同步的 主线程代码
  2. 清空微任务队列
  3. 如有需要,执行渲染更新(requestAnimationFrame)
  4. 从宏任务队列取一个任务执行
  5. 重复步骤 2-4
💡 提示 微任务的优先级高于宏任务,每个宏任务执行完后都会清空微任务队列。

12. 渲染完成

渲染树构建 -> 布局 -> 绘制 -> 合成
最终页面呈现在用户面前。


结语

从地址栏输入 URL 到页面出现在屏幕上,浏览器、网络、操作系统、服务器共同协作完成了多个步骤。这篇文章从网络协议到渲染原理,梳理了整个过程的主干逻辑,希望能帮助你在实际开发中更准确地理解页面加载的每一个环节。