跳转到内容
创建时间: 2022年11月19日

一、浏览器整体架构(宏观认知) ​

现代浏览器(以 Chrome / Chromium 为例)是多进程架构:

浏览器主进程
 ├── 网络进程
 ├── GPU 进程
 ├── 渲染进程(每个 Tab / iframe)
 │     ├── JS 引擎(V8)
 │     ├── 渲染引擎(Blink)
 │     ├── 事件循环
 │     └── Web API
 └── 插件进程

为什么要多进程? ​

  • ✅ 安全(沙箱隔离)
  • ✅ 稳定(一个页面崩溃不影响其他)
  • ✅ 性能(并行执行)

二、从输入 URL 到页面显示(完整链路) ​

这是面试必考主线。

1️⃣ URL 解析 ​

  • 补全协议
  • 判断是搜索还是网址
  • DNS 解析 → IP

2️⃣ 网络请求(Network) ​

  • TCP 三次握手
  • HTTPS:TLS 握手
  • HTTP 请求 / 响应
  • 缓存策略(强缓存 / 协商缓存)

3️⃣ 构建 DOM & CSSOM(渲染前置条件) ​

HTML ──> DOM Tree
CSS  ──> CSSOM Tree
  • ⚠️ CSS 会阻塞渲染
  • ⚠️ JS 会阻塞 DOM 解析

三、关键:浏览器渲染流水线(核心) ​

🌈 浏览器渲染五大阶段 ​

DOM + CSSOM
   ↓
Render Tree
   ↓
Layout(回流 / 重排)
   ↓
Paint(重绘)
   ↓
Composite(合成)

下面逐个拆解。

四、Render Tree(渲染树) ​

渲染树 ≠ DOM 树

特点:

  • 只包含可见节点
  • display: none ❌
  • visibility: hidden ✅(占位)
DOM + CSSOM → Render Tree

五、Layout(回流 / 重排) ​

👉 计算元素的几何信息

  • 位置
  • 宽高
  • 盒模型

触发回流的操作(⚠️ 性能杀手) ​

  • 改变:

    • width / height
    • padding / margin
    • position / display
  • 读取:

    • offsetTop
    • clientHeight
    • getBoundingClientRect()

📌 回流一定会导致重绘

六、Paint(重绘) ​

👉 把像素绘制到位图

触发重绘但不回流:

  • color
  • background
  • box-shadow
  • outline

📌 重绘不一定回流

七、Composite(合成 / GPU 加速) ​

👉 多个图层交给 GPU 合成

能触发合成层(重点) ​

  • transform
  • opacity
  • will-change
  • position: fixed
  • video / canvas

✨ 只走 Composite,性能最好

八、JS 与渲染的关系(事件循环) ​

JS 是单线程的 ​

  • JS 执行时
  • 渲染会被阻塞

Event Loop 简化模型 ​

宏任务(script / setTimeout)
   ↓
微任务(Promise / MutationObserver)
   ↓
渲染(layout / paint)

📌 微任务清空后才会渲染

九、浏览器优化策略(工程实践) ​

1️⃣ 减少回流 ​

js
// ❌ 多次回流
el.style.width = '100px'
el.style.height = '100px'

// ✅ 合并
el.style.cssText = 'width:100px;height:100px'

2️⃣ 读写分离 ​

js
// ❌
el.style.width = el.offsetWidth + 10 + 'px'

// ✅
const w = el.offsetWidth
el.style.width = w + 10 + 'px'

3️⃣ 使用 transform 替代 top/left ​

css
/* ❌ */
left: 100px;

/* ✅ */
transform: translateX(100px);

十、浏览器渲染相关高频面试题 ​

❓ 为什么 CSS 放在 head,JS 放在 body? ​

  • CSS 阻塞渲染
  • JS 阻塞 DOM 解析

❓ async vs defer ​

属性是否阻塞执行时机
async❌下载完成立即执行
defer❌DOM 解析完成后

❓ requestAnimationFrame ​

  • 在 下一帧渲染前执行
  • 适合动画