ZDecode
Browser

渲染原理

一、浏览器渲染 HTML 的过程(简化版)

当浏览器加载一个 HTML 页面时,大致经历以下几个阶段:

  1. 解析 HTML,构建 DOM 树

    • 浏览器从上到下解析 HTML,生成 DOM(Document Object Model)。
  2. 解析 CSS,构建 CSSOM 树

    • 解析 <style>、外链 CSS 等资源,构建 CSSOM(CSS Object Model)。
  3. 合并 DOM 和 CSSOM,生成 Render Tree

    • 每个可见节点(如 display: none 不会参与)根据样式生成渲染树节点。
  4. 布局(Layout)阶段

    • 又称 回流(Reflow),计算每个节点的几何位置和大小。
  5. 绘制(Paint)阶段

    • 又称 重绘(Repaint),将每个节点的像素信息绘制到屏幕上。
  6. 分层和合成(Compositing)

    • 复杂的节点(如 3D、transform、动画)会单独分层,由 GPU 合成最终页面。

二、回流(Reflow)与重绘(Repaint)

概念回流(Reflow)重绘(Repaint)
触发条件DOM 结构变化、元素位置/大小变化、字体改变元素样式变化(颜色、visibility等)
影响范围当前节点及其子树,可能影响整个文档只影响外观,不影响布局
性能消耗较高较低
示例改变 widthpaddingdisplay改变 colorbackground-color

三、基于回流和重绘的常见前端性能优化技巧

  1. 减少回流频率

    • 合并多次 DOM 操作
    // 不推荐
    for (let i = 0; i < 1000; i++) {
      list.appendChild(createItem(i));
    }
    
    // 推荐:使用 DocumentFragment
    const fragment = document.createDocumentFragment();
    for (let i = 0; i < 1000; i++) {
      fragment.appendChild(createItem(i));
    }
    list.appendChild(fragment);
    • 使用 className 替代多个 style 操作
    // 多次触发重绘 + 回流
    el.style.width = '100px';
    el.style.height = '100px';
    
    // 推荐
    el.className = 'my-style';
    • 避免逐帧同步读取 layout 信息
        // 错误做法(会强制回流)
    const height = el.offsetHeight;
    el.style.height = height + 'px';
  2. 使用虚拟 DOM/批量更新框架

React、Vue 等框架有 diff 算法和异步批量更新,能减少不必要的回流。

  1. 使用 will-change 让浏览器提前优化
.card {
  will-change: transform;
}

适用于即将频繁变化的属性(如动画中的 transform, opacity)。

  1. 使用 transform/opacity 替代影响布局的属性

    • transform: translateX() vs left: 100px:前者只触发合成,不回流也不重绘。

    • opacity 动画比 background-color 更轻量(硬件加速)。

总结

浏览器渲染过程核心包括:DOM 解析CSSOM 解析Render Tree 构建回流重绘合成

回流和重绘频繁发生会严重影响性能,关键是减少 DOM 操作频率批量处理尽量避免触发布局计算

利用虚拟 DOM硬件加速动画优化等方式能显著提升性能。