这道题是前端面试的经典必考题,考察范围横跨计算机网络、操作系统、浏览器架构和前端渲染,能答好的人并不多。大多数人要么只讲 DNS + TCP + HTTP,要么堆砌知识点却没有逻辑。本文尝试按照真实的执行链路,把每个环节串起来讲清楚。
浏览器是多进程架构
在讲 URL 流程之前,先建立一个基础认知:浏览器是多进程架构。
操作系统中:
- 进程(Process) :资源分配的最小单元,拥有独立的内存空间
- 线程(Thread) :执行的最小单元,线程跑在进程里,共享进程内存
浏览器不是一个单一进程,它由多个进程协同工作:
| 进程 | 职责 |
|---|---|
| 浏览器主进程 | 用户交互、子进程管理、文件存储(缓存/Cookie/localStorage) |
| 网络进程 | 负责网络请求的发起与响应 |
| 渲染进程 | 负责 HTML、CSS、JS 的解析与页面渲染 |
| GPU 进程 | 合成图层、硬件加速 |
| 插件进程 | 隔离运行浏览器插件 |
进程之间通过 IPC(Inter-Process Communication,进程间通信) 来传递消息。后面整个 URL 流程,本质上就是这些进程不断协作、通过 IPC 传递数据的过程。
第一阶段:浏览器主进程处理输入
用户在地址栏输入内容,浏览器主进程首先介入。它需要判断用户输入的是什么:
情况一:输入的是搜索关键词
浏览器会拼接默认搜索引擎的 URL,比如 Google:
https://www.google.com/search?q=关键词
情况二:输入的是网址
浏览器会对 URL 进行补全,例如用户输入 time.geekbang.org,浏览器自动补全为:
https://time.geekbang.org
情况三:HTTP 跳转 HTTPS
如果用户手动输入了 http://time.geekbang.org,服务器会返回 301 或 302 重定向响应:
HTTP/1.1 301 Moved Permanently
Location: https://time.geekbang.org
浏览器读取 Location 字段,强制跳转到 HTTPS 地址,重新发起请求。这是服务器帮用户"纠正习惯"的常见做法。
确定最终 URL 后,浏览器主进程通过 IPC 将 URL 转发给网络进程,同时页面标签开始显示 loading 图标,浏览历史栈压入新记录,旧页面触发 beforeunload 事件。
第二阶段:DNS 解析——域名换 IP
网络进程拿到 URL 后,第一步是解析出目标服务器的 IP 地址。计算机底层通信用的是 IP,而不是人类可读的域名,这个转换过程由 DNS(Domain Name System) 完成。
DNS 是一个分布式的 key-value 数据库:
time.geekbang.org → 36.155.132.55
查询链路从近到远,依次是:
- 浏览器本地 DNS 缓存:访问过的域名会被短暂缓存
- 操作系统 hosts 文件:本地配置的域名映射
- 局域网/本地 DNS 服务器:由运营商或企业提供
- 根域名服务器:全球 13 组,中国通过海底光缆连接
- 顶级域名服务器(TLD) :负责
.com、.org等 - 权威域名服务器:持有该域名的真实 IP 记录
这是 OSI 七层协议中应用层的工作,最终目的就是拿到一个 IP 地址,让后续 TCP 连接有目标可打。
第三阶段:建立连接——TCP 三次握手
有了 IP 地址,网络进程开始与服务器建立 TCP 连接。TCP 是可靠传输协议,三次握手确保双方都具备收发数据的能力:
客户端 → 服务端:SYN(我要连你)
服务端 → 客户端:SYN + ACK(收到,我也准备好了)
客户端 → 服务端:ACK(好的,开始吧)
三次握手完成后,连接建立。如果是 HTTPS,还需要在 TCP 之上完成 TLS 握手:交换证书、协商加密算法、生成会话密钥,整个过程会多 1~2 个 RTT(往返延迟)。
第四阶段:发送 HTTP 请求
连接建立后,网络进程构造并发送 HTTP 请求,主要包含两部分:
请求行:
GET /index.html HTTP/1.1
包含请求方法(GET/POST 等)、请求路径、HTTP 版本。
请求头:
Host: time.geekbang.org
Authorization: Bearer <jwt_token>
Cookie: session_id=xxx
Cache-Control: max-age=0
这里有几个关键字段:
Authorization:携带 JWT Token,用于身份验证Cookie:浏览器自动附带,服务端用于会话识别Cache-Control:告诉服务器/代理如何使用缓存
第五阶段:服务器响应——Content-Type 决定浏览器行为
服务器处理请求后返回响应,网络进程先解析响应头,根据 Content-Type 决定如何处理响应体,然后再通知浏览器主进程:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Type 的值直接决定了浏览器的下一步动作:
| Content-Type | 浏览器行为 |
|---|---|
text/html | 通知渲染进程准备接收,进入页面渲染流程 |
text/css / image/jpeg | 触发文件下载或作为子资源缓存 |
application/octet-stream | 触发文件下载对话框 |
状态码也在这里起作用:200 正常、301/302 重定向、304 协商缓存命中、404 资源不存在、500 服务器错误。
第六阶段:导航提交——进程间协作的核心环节
这一段是最容易被忽略的,也是最能体现浏览器多进程架构价值的部分。
当网络进程解析到 Content-Type: text/html 后,整个协作流程如下:
- 网络进程 → 浏览器主进程:通过 IPC 告知"已拿到 HTML 响应头,是页面内容"
- 浏览器主进程 → 渲染进程:发出"提交导航"消息,通知渲染进程准备接收数据
- 渲染进程 → 浏览器主进程:回复"确认提交",表示准备就绪
- 渲染进程与网络进程之间建立数据管道:HTML 数据流开始传输
- 渲染进程 → 浏览器主进程:数据接收完毕,发出"提交文档"消息
- 浏览器主进程:移除旧文档,更新页面状态,loading 图标消失
从用户输入 URL 到页面开始解析的这整个过程,就叫做导航(Navigation) 。
第七阶段:渲染进程的工作——从 HTML 到像素
数据到达渲染进程后,进入前端最熟悉的渲染流水线:
1. 构建 DOM 树 HTML 字节流 → 词法分析(Tokenization)→ 构建 DOM Tree
2. 构建 CSSOM 树 解析 CSS,构建样式规则树(CSSOM)
3. 合并为渲染树(Render Tree) DOM + CSSOM 合并,只包含可见节点(display:none 的节点不在其中)
4. 布局(Layout) 计算每个节点的位置和尺寸(回流/Reflow 就发生在这里)
5. 分层(Layer) 根据层叠上下文、will-change、transform 等属性,将页面分成多个图层
6. 绘制(Paint) 生成每个图层的绘制指令列表
7. 合成(Composite) GPU 进程将各图层合并,最终输出到屏幕
这也是为什么 CSS 动画优先使用 transform 和 opacity——它们只触发合成阶段,跳过了 Layout 和 Paint,性能最优。
一张思维导图串联全流程
用户输入 URL
↓
浏览器主进程:判断输入类型 → URL 补全 / 搜索词处理
↓
网络进程:DNS 解析 → 获取 IP
↓
TCP 三次握手 → (HTTPS) TLS 握手
↓
发送 HTTP 请求(请求行 + 请求头)
↓
服务器返回响应(响应头 → Content-Type 判断)
↓
导航提交:主进程 ↔ 渲染进程 ↔ 网络进程 IPC 协作
↓
渲染进程:DOM → CSSOM → Render Tree → Layout → Paint → Composite
↓
页面呈现
小结
这道题真正考的是知识体系的完整性和表达的逻辑性,而不是某个孤立知识点的深度。建议答题时按照"输入处理 → DNS → TCP → HTTP → 响应判断 → 导航提交 → 渲染流水线"这条主线展开,每个环节点到核心概念即可,切忌把 TCP 三次握手的 Flag 位全背一遍却忘了讲渲染进程是怎么拿到数据的。
前端工程师能把浏览器的多进程架构和进程间 IPC 协作讲清楚,往往是和其他候选人拉开差距的地方。