外观
URL 输入到浏览器响应经历了什么
⭐ 题目日期:
美团 - 2025/04/12,字节 - 2024/09/03
📝 题解:
从输入 URL 到浏览器渲染出完整页面,整个过程涉及 网络通信、浏览器引擎协作、渲染流水线 等多个阶段。以下是详细的流程解析:
1. URL 解析与预处理
- 检查输入合法性 浏览器判断输入是 URL 还是搜索关键词。若为关键词,跳转默认搜索引擎(如
https://www.google.com/search?q=keyword
)。 - 协议补全 自动补全协议头(如输入 example.com 补全为 https://example.com)。
- HSTS 检查 若域名在浏览器的 HSTS(HTTP Strict Transport Security)列表中,强制使用 HTTPS。
2. DNS 解析
查找本地缓存 依次检查浏览器缓存 → 操作系统缓存(/etc/hosts) → 路由器缓存。
递归查询 DNS 服务器 若缓存未命中,向配置的 DNS 服务器(如 8.8.8.8)发起查询,流程如下:
本地 DNS → 根域名服务器 → 顶级域名服务器(.com) → 权威域名服务器 → 返回 IP 地址
DNS 优化
- DNS 预解析:通过
<link rel="dns-prefetch">
提前解析域名。 - CDN 加速:根据用户位置返回最近的服务器 IP。
- DNS 预解析:通过
3. 建立 TCP 连接
- 三次握手(Three-Way Handshake) 浏览器与服务器建立 TCP 连接:
- 客户端发送
SYN
(同步序列号)包(Seq = x)。 - 服务器返回
SYN-ACK
包(Seq = y, ACK = x+1)。 - 客户端发送
ACK
包(ACK = y+1),连接建立。
- 客户端发送
- TLS 握手(HTTPS 场景) 若使用 HTTPS,需完成 TLS 握手:
- 客户端发送
ClientHello
(支持的加密套件、随机数等)。 - 服务器返回
ServerHello
(选定加密套件、证书、随机数等)。 - 客户端验证证书,生成预主密钥(Pre-Master Secret)并用公钥加密发送。
- 双方通过随机数和预主密钥生成会话密钥,完成加密通道建立。
- 客户端发送
4. 发送 HTTP 请求
- 构造请求报文 浏览器生成 HTTP 请求头,包含:
GET /index.html HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 Accept-Encoding: gzip, deflate Cookie: session_id=abc123
- 请求优化
- HTTP/2 多路复用:同一连接并行传输多个请求,避免队头阻塞。
- 请求压缩:使用
Accept-Encoding
声明支持的压缩算法(如 Brotli、Gzip)。
5. 服务器处理请求
- 反向代理与负载均衡 请求可能先到达反向代理(如 Nginx),根据规则转发到应用服务器(如 Node.js、Java)。
- 静态资源处理 若请求 HTML/CSS/JS 等静态文件,直接读取并返回。
- 动态内容处理 若涉及数据库查询(如 MySQL)或业务逻辑,执行后生成响应内容。
- 缓存策略 根据
Cache-Control
和ETag
判断是否返回 304(Not Modified)。
6. 接收 HTTP 响应
- 解析响应头 浏览器读取状态码(如
200 OK
)、内容类型(Content-Type: text/html
)、缓存指令等。 - 处理响应体
- 解压缩:根据
Content-Encoding
解压数据(如 Gzip)。 - 流式处理:边接收边解析(用于大文件或视频流)。
- 解压缩:根据
7. 浏览器渲染
构建 DOM 树
- 解析 HTML 将 HTML 转换为 DOM(Document Object Model)树,遇到
<script>
时可能阻塞解析。 - 预加载扫描器(Preload Scanner) 提前发现资源(如图片、CSS)并触发下载。
构建 CSSOM 树
- 解析 CSS 将 CSS 转换为 CSSOM(CSS Object Model)树,解析顺序影响最终样式。
合成渲染树(Render Tree)
- 合并 DOM 和 CSSOM,排除不可见节点(如
<head>
、display: none
)。
布局(Layout/Reflow)
- 计算几何信息 确定每个节点的位置和尺寸(视口大小、盒模型等)。
- 重排优化 避免频繁修改样式(如使用
transform
替代top/left
)。
绘制(Painting)
- 生成绘制指令 将渲染树转换为屏幕上的像素(如填充颜色、绘制边框)。
- 分层与合成 使用 GPU 加速合成层(如
will-change: transform
)。
最终呈现
- 显示(Display) 将合成后的图层提交到显卡缓冲区,刷新屏幕。
8. 后续交互
- JavaScript 执行 执行
DOMContentLoaded
和load
事件回调。 - 异步加载 按需加载图片、字体等非关键资源。
- 事件循环(Event Loop) 处理用户输入、网络事件、定时器等异步任务。
关键性能优化点
- 减少 DNS 查询:使用 DNS 预解析或 HTTP/2 服务器推送。
- TCP 快速打开(TFO):在 SYN 包中携带数据,减少握手延迟。
- 启用 Brotli 压缩:比 Gzip 节省 15%~25% 带宽。
- 避免重定向:减少额外的 HTTP 请求。
- 关键渲染路径优化:内联关键 CSS、延迟加载非关键 JS。
示例:加载 https://example.com
的完整流程
- 输入 URL → 补全为 HTTPS → HSTS 检查 → DNS 解析获得 IP
- TCP 三次握手 → TLS 握手 → 发送 HTTP GET 请求
- 服务器返回 HTML → 浏览器解析生成 DOM
- 解析 CSS 生成 CSSOM → 合成渲染树 → 布局 → 绘制
- 执行 JavaScript → 加载图片等资源 → 页面完全交互