从URL输入到页面渲染的全流程
从URL输入到页面渲染的全流程
OHNII核心流程(9个关键步骤)
记忆口诀:URL解析 → DNS查询 → TCP连接 → HTTP请求 → 服务器响应 → 解析HTML → 构建DOM/CSSOM → 渲染树 → 绘制显示
1. URL解析
- 浏览器解析输入的URL,提取协议(http/https)、域名、端口、路径等信息
- 检查URL合法性,判断是搜索关键词还是网址
- 如果是HTTPS,后续需要进行SSL/TLS握手
2. DNS域名解析(查找IP地址)
流程:浏览器缓存 → 系统缓存 → 路由器缓存 → ISP DNS → 根域名服务器 → 顶级域名服务器 → 权威域名服务器
- 浏览器先查看自身DNS缓存
- 查看操作系统hosts文件和系统DNS缓存
- 向本地DNS服务器(ISP提供)发起查询
- 递归查询:根DNS → 顶级域名DNS(.com) → 权威DNS
- 返回目标服务器IP地址
3. 建立TCP连接(三次握手)
流程:SYN → SYN+ACK → ACK
- 客户端发送SYN包(请求建立连接)
- 服务器返回SYN+ACK包(确认并请求连接)
- 客户端发送ACK包(确认连接建立)
为什么三次握手?
- 确保双方都有发送和接收能力
- 防止已失效的连接请求突然传到服务器
4. 发送HTTP请求
请求组成:请求行 + 请求头 + 请求体
1 | GET /index.html HTTP/1.1 |
- 请求方法:GET、POST、PUT、DELETE等
- 携带Cookie、Token等认证信息
- 如果是HTTPS,数据会被加密传输
5. 服务器处理并返回响应
响应组成:状态行 + 响应头 + 响应体
1 | HTTP/1.1 200 OK |
- 状态码:200成功、301重定向、404未找到、500服务器错误
- 响应头包含内容类型、缓存策略、Cookie等
- 响应体是HTML、CSS、JS等资源
6. 浏览器解析HTML(构建DOM树)
流程:字节 → 字符 → 令牌 → 节点 → DOM树
- 解析HTML标签,构建DOM树(Document Object Model)
- 遇到
<link>标签,异步下载CSS(不阻塞DOM构建) - 遇到
<script>标签:- 普通script:阻塞DOM解析,立即下载并执行
async:异步下载,下载完立即执行(可能阻塞)defer:异步下载,DOM解析完后按顺序执行
7. 解析CSS(构建CSSOM树)
流程:字节 → 字符 → 令牌 → 节点 → CSSOM树
- 解析CSS规则,构建CSSOM树(CSS Object Model)
- CSS解析会阻塞渲染,但不阻塞DOM解析
- 计算样式优先级(内联 > ID > 类 > 标签)
8. 构建渲染树(Render Tree)
流程:DOM树 + CSSOM树 → 渲染树
- 将DOM树和CSSOM树合并
- 只包含可见节点(
display:none的节点不在渲染树中) - 计算每个节点的样式(Recalculate Style)
9. 布局与绘制
流程:布局(Layout/Reflow) → 绘制(Paint) → 合成(Composite)
布局(Layout/Reflow)
- 计算每个节点的几何信息(位置、大小)
- 从根节点递归计算
绘制(Paint)
- 将渲染树转换为屏幕上的像素
- 分层绘制(图层、文本、边框等)
合成(Composite)
- 将多个图层合成最终页面
- GPU加速(transform、opacity等属性)
性能优化关键点
减少重排(Reflow)
- 避免频繁修改DOM
- 使用
transform代替top/left - 批量修改样式
- 使用
DocumentFragment
减少重绘(Repaint)
- 避免频繁修改颜色、背景等
- 使用CSS3动画(GPU加速)
资源加载优化
- CSS放在
<head>中(尽早加载) - JS放在
</body>前或使用defer/async - 使用CDN加速
- 开启Gzip压缩
- 使用HTTP/2多路复用
- 资源懒加载
缓存策略
- 强缓存:
Cache-Control、Expires - 协商缓存:
ETag、Last-Modified
面试口述版本(精简版)
面试官:请描述从输入URL到页面显示的完整过程
回答框架:
“这个过程可以分为9个关键步骤:
URL解析:浏览器解析URL,提取协议、域名、路径等信息
DNS解析:通过DNS查询将域名转换为IP地址,查询顺序是浏览器缓存、系统缓存、路由器缓存、ISP DNS服务器
建立TCP连接:通过三次握手建立TCP连接,确保客户端和服务器都能正常收发数据
发送HTTP请求:浏览器构造HTTP请求报文,包含请求方法、请求头、Cookie等信息
服务器处理:服务器接收请求,处理业务逻辑,返回HTTP响应,包含状态码、响应头和HTML内容
解析HTML构建DOM树:浏览器解析HTML标签,构建DOM树。遇到CSS异步加载,遇到JS会阻塞解析
解析CSS构建CSSOM树:解析CSS规则,构建CSSOM树,计算样式优先级
构建渲染树:将DOM树和CSSOM树合并,生成渲染树,只包含可见节点
布局与绘制:计算节点的几何信息(布局),将渲染树绘制成像素(绘制),最后合成显示在屏幕上
性能优化方面,可以通过减少重排重绘、优化资源加载顺序、使用缓存策略、开启Gzip压缩等方式提升性能。”
高频追问
Q1: 为什么CSS要放在head中,JS要放在body底部?
- CSS放head:尽早加载样式,避免页面闪烁(FOUC)
- JS放底部:避免阻塞DOM解析,提升首屏渲染速度
- 现代方案:JS使用
defer或async属性
Q2: 重排和重绘的区别?
- 重排(Reflow):元素几何属性变化(位置、大小),需要重新计算布局,开销大
- 重绘(Repaint):元素样式变化(颜色、背景),不影响布局,开销小
- 重排一定重绘,重绘不一定重排
Q3: 如何减少重排?
- 批量修改DOM(使用
DocumentFragment) - 使用
transform代替top/left - 避免逐条修改样式,使用class
- 将DOM离线后修改(
display:none) - 使用
requestAnimationFrame
Q4: 浏览器的缓存策略?
- 强缓存:
Cache-Control(优先)、Expires,直接使用缓存,不请求服务器 - 协商缓存:
ETag/If-None-Match、Last-Modified/If-Modified-Since,询问服务器是否可用缓存
Q5: TCP为什么是三次握手,四次挥手?
- 三次握手:确保双方收发能力正常,防止失效请求
- 四次挥手:因为TCP是全双工,需要双方分别关闭发送通道,所以需要四次

