Yasin

Yasin

从输入 URL 到看到网页

从输入 URL 到看到网页


完整流程

输入 URL
1. DNS 解析
2. 建立 TCP 连接
3. 发送 HTTP 请求
4. 服务器返回响应
5. 浏览器解析 HTML
6. 构建 DOM 树
7. 构建 CSSOM 树
8. 构建渲染树
9. 布局(Layout)
10. 绘制(Paint)
用户看到页面

1. DNS 解析

把域名翻译成 IP 地址。

输入:www.example.com
查本地缓存(浏览器缓存 → 系统缓存 → hosts 文件)
  ↓ 没有缓存
查 DNS 服务器
返回 IP:93.184.216.34

2. 建立 TCP 连接(三次握手)

找到服务器 IP 后,建立可靠连接:

客户端 → SYN(我想连接你)→ 服务器
客户端 ← SYN+ACK(好的,我准备好了)← 服务器
客户端 → ACK(收到,开始通信)→ 服务器

如果是 HTTPS,还需要额外的 TLS 握手(协商加密方式、交换证书)。


3. 发送 HTTP 请求

TCP 连接建立后,浏览器发送请求:

GET / HTTP/1.1
Host: www.example.com
User-Agent: Chrome/...
Accept: text/html
Cookie: ...

4. 服务器返回响应

服务器处理请求,返回:

HTTP/1.1 200 OK
Content-Type: text/html
Cache-Control: max-age=3600

<!DOCTYPE html>
<html>...

5. 浏览器解析 HTML,构建 DOM 树

浏览器从上到下解析 HTML:

HTML 字节流
  ↓ 解码
字符串
  ↓ 词法分析(Tokenize)
Token(标签、文本)
  ↓ 语法分析
DOM 树

<html>
  <body>
    <div>
      <p>Hello</p>
    </div>
  </body>
</html>

6. 遇到资源怎么处理

解析 HTML 过程中遇到各种资源:

  • CSS:下载并解析,构建 CSSOM,不阻塞 HTML 解析,但阻塞渲染
  • JS(没有 async/defer)立刻暂停 HTML 解析,下载并执行完再继续
  • JS(async):异步下载,下载完立刻执行
  • JS(defer):异步下载,HTML 解析完再执行
  • 图片:异步下载,不阻塞解析

7. 构建 CSSOM 树

CSS 文件
  ↓ 解析
CSSOM 树(每个节点包含样式信息)

8. 构建渲染树(Render Tree)

DOM 树 + CSSOM 树 = 渲染树

DOM 树          CSSOM 树
   +                +
      ↘          ↙
       渲染树
(只包含可见节点,display:none 的不在渲染树里)

9. 布局(Layout / Reflow)

计算每个节点的位置和大小

渲染树
计算每个元素的:
  - 坐标(x, y)
  - 尺寸(width, height)
  - 相对/绝对位置

10. 绘制(Paint)

把布局结果画到屏幕上

布局信息
绘制文字、颜色、边框、阴影...
合成图层(Composite)
显示到屏幕

关键性能节点

节点 说明
TTFB(首字节时间) 从请求到收到第一个字节
FCP(首次内容绘制) 页面第一个内容出现
LCP(最大内容绘制) 最大元素渲染完成
TTI(可交互时间) 页面可以响应用户操作

优化方向

  • DNS 预解析<link rel="dns-prefetch" href="//cdn.example.com">
  • 减少请求体积:代码压缩、图片优化
  • 缓存:静态资源加 hash + 长期缓存
  • JS 不阻塞渲染:script 加 defer
  • CSS 不阻塞渲染:关键 CSS 内联,非关键 CSS 异步加载
  • SSR:服务端直接返回完整 HTML,减少白屏时间