从输入 URL 到页面展示的全过程
这是一道经典的浏览器原理面试题,它串联了网络、解析、渲染、执行等所有核心知识点。
我们将整个过程划分为 网络请求 和 页面渲染 两个阶段。
第一阶段:网络请求 (Network)
1. URL 解析与构建请求
- 输入检查:浏览器判断输入的是 URL 还是搜索关键字。
- 构建请求:构建 HTTP 请求行(Get / HTTP/1.1)。
2. 查找缓存 (Cache Lookup)
- 强缓存:浏览器检查本地缓存(Expires / Cache-Control)。
- 如果命中且未过期,直接使用,状态码 200 (from disk/memory cache)。也不需要发请求。
- 如果没命中或过期,进入下一步。
3. DNS 域名解析 (DNS Resolution)
- 浏览器需要获取域名的 IP 地址。
- 查询顺序:浏览器缓存 -> 操作系统缓存 (hosts) -> 路由器缓存 -> ISP DNS 服务器 -> 根域名服务器递归查询。
- 优化:DNS Prefetch。
4. 建立 TCP 连接 (TCP Handshake)
- 与服务器 IP 建立连接。
- 三次握手:
- SYN:客户端发送连接请求。
- SYN + ACK:服务器确认并同意连接。
- ACK:客户端确认。连接建立。
5. 发送 HTTP 请求
- 携带 Cookies、Headers 等信息。
- 如果之前是强缓存失效,这里会带上
If-Modified-Since或If-None-Match走协商缓存。
6. 服务器处理与响应
- 服务器接收请求,处理逻辑(如查询数据库)。
- 协商缓存检查:如果资源未变,返回 304,浏览器读本地副本。
- 否则返回 200 + 响应体(HTML)。
7. 断开 TCP 连接
- 四次挥手。
- 如果是 HTTP/1.1
Connection: keep-alive,则连接会保持一段时间,供后续资源下载复用。
第二阶段:页面渲染 (Rendering)
浏览器主进程收到 HTML 数据后,将其发送给渲染进程,开始渲染。
1. 构建 DOM 树
- 字节 -> 字符 -> Token -> Node -> DOM Tree。
- 遇到
<script>会阻塞解析(除非 async/defer)。
2. 构建 CSSOM 树
- 解析 CSS(link/style),构建 CSSOM Tree。
- CSS 解析不阻塞 DOM 构建,但阻塞渲染。
3. 生成渲染树 (Render Tree)
- 结合 DOM 和 CSSOM。
- 去除不可见节点(如
head,display: none)。
4. 布局 (Layout)
- 计算渲染树中每个节点的位置和大小。
- 这一步也叫 Reflow(回流)。
5. 绘制 (Paint)
- 生成绘制指令(如“画一个红色矩形”)。
- 分层绘制(Layer)。
6. 合成 (Composite)
- 将各层图块栅格化(Rasterize)。
- GPU 将位图合成到屏幕上。
总结流程图
mermaid
graph TD
User[用户输入 URL] --> Cache{检查强缓存}
Cache --命中--> Render[渲染流程]
Cache --未命中--> DNS[DNS 解析]
DNS --> TCP[TCP 三次握手]
TCP --> Request[发送 HTTP 请求]
Request --> Response{服务器响应}
Response --304--> Local[读本地缓存]
Local --> Render
Response --200--> Render
subgraph RenderProcess [渲染流程]
HTML --> DOM[DOM 树]
CSS --> CSSOM[CSSOM 树]
DOM & CSSOM --> RenderTree[渲染树]
RenderTree --> Layout[布局]
Layout --> Paint[绘制]
Paint --> Composite[合成显示]
end这个过程体现了所有性能优化的关键点:
- DNS -> DNS Prefetch
- TCP -> HTTP/2, Keep-Alive
- Request -> 减小体积 (Gzip), 减少次数 (雪碧图)
- Cache -> 强缓存策略
- DOM/CSS -> 减少重排重绘, 关键渲染路径优化