Skip to content

URL 输入到浏览器响应经历了什么

约 1240 字大约 4 分钟

计算机网络字节美团

2025-04-25

⭐ 题目日期:

美团 - 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。

3. 建立 TCP 连接

  • 三次握手(Three-Way Handshake)​ 浏览器与服务器建立 TCP 连接:
    1. 客户端发送 SYN(同步序列号)包(Seq = x)。
    2. 服务器返回 SYN-ACK 包(Seq = y, ACK = x+1)。
    3. 客户端发送 ACK 包(ACK = y+1),连接建立。
  • TLS 握手(HTTPS 场景)​ 若使用 HTTPS,需完成 TLS 握手:
    1. 客户端发送 ClientHello(支持的加密套件、随机数等)。
    2. 服务器返回 ServerHello(选定加密套件、证书、随机数等)。
    3. 客户端验证证书,生成预主密钥(Pre-Master Secret)并用公钥加密发送。
    4. 双方通过随机数和预主密钥生成会话密钥,完成加密通道建立。

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-ControlETag 判断是否返回 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 执行 执行 DOMContentLoadedload 事件回调。
  • 异步加载 按需加载图片、字体等非关键资源。
  • 事件循环(Event Loop)​ 处理用户输入、网络事件、定时器等异步任务。

关键性能优化点

  1. 减少 DNS 查询:使用 DNS 预解析或 HTTP/2 服务器推送。
  2. TCP 快速打开(TFO)​:在 SYN 包中携带数据,减少握手延迟。
  3. 启用 Brotli 压缩:比 Gzip 节省 15%~25% 带宽。
  4. 避免重定向:减少额外的 HTTP 请求。
  5. 关键渲染路径优化:内联关键 CSS、延迟加载非关键 JS。

示例:加载 https://example.com 的完整流程

  1. 输入 URL → 补全为 HTTPS → HSTS 检查 → DNS 解析获得 IP
  2. TCP 三次握手 → TLS 握手 → 发送 HTTP GET 请求
  3. 服务器返回 HTML → 浏览器解析生成 DOM
  4. 解析 CSS 生成 CSSOM → 合成渲染树 → 布局 → 绘制
  5. 执行 JavaScript → 加载图片等资源 → 页面完全交互