元素在渲染过程中会涉及到性能问题,元素的展示回流和重绘是如何影响的?

在这里插入图片描述

回流和重绘

回流 (Reflow)

  • 定义:当渲染树(Render Tree)中的一部分或全部因为元素尺寸、布局、隐藏等改变而需要重新构建布局的过程
  • 触发条件
    • 页面首次渲染(最核心的回流场景)。
    • 添加/删除/移动DOM元素
    • 元素尺寸/位置变化(宽高、边距、定位position、display从非none变为none等)
    • 窗口大小改变、滚动页面
    • 字体大小改变
    • 读取offset系列、scroll系列、client系列、getComputedStyle等布局属性(浏览器为获取准确值会强制回流)

为什么在获取属性时也会造成回流,因为浏览器会批量计算页面布局,有可能会无法拿到最新的属性值,所以每次获取都会重新触发回流。

重绘 (Repaint)

  • 定义:当元素样式改变但不影响布局时,浏览器重新绘制元素外观的过程
  • 触发条件
    • 颜色改变color
    • 背景色/背景图改变
    • 边框样式改变
    • visibility改变
    • outline等

关系:回流一定会触发重绘,但重绘不一定会触发回流


为什么推荐使用transform实现动画

在说明这个之前,我们应该来先理解下浏览器渲染的整个过程,涉及到以下步骤:

HTML解析样式计算布局分层绘制分块光栅化。而我们所说的transform就是在合成线程中处理,与主线程无关,这就是推荐使用的原因。

在这里插入图片描述

优势

  1. 硬件加速

    • 现代浏览器会将transform动画交给GPU处理
    • 开启3D变换(如translate3d)可强制使用GPU加速
  2. 避免回流

    • transform修改的是元素的合成层属性,而合成层属性渲染不会影响渲染主线程
    • 动画过程中不会触发回流和重绘,只在合成阶段处理
  3. 独立图层

    • transform动画元素会被提升到独立的合成层
    • 避免影响其他元素的渲染
  4. 更流畅的60fps

    • 动画在合成线程执行,不阻塞主线程
    • 即使是JavaScript控制的transform动画也比直接修改样式性能更好

transform动画 VS 传统动画对比

特性 transform动画 传统动画(修改top/left等)
性能 GPU加速,性能高 CPU处理,性能较低
回流 不触发回流 触发回流,性能开销大
流畅度 60fps流畅动画 可能出现卡顿、掉帧
能耗 GPU能耗高但时间短 CPU持续高负载
适用场景 复杂动画、移动端 简单状态变化

推荐做法

/* 推荐 - 使用transform */
.element {
  transition: transform 0.3s ease;
  transform: translateX(100px);
}
/* 不推荐 - 修改布局属性 */
.element {
  transition: left 0.3s ease;
  left: 100px;
}

支持的transform属性

  • translate() - 位置移动(替代top/left)
  • scale() - 缩放
  • rotate() - 旋转
  • skew() - 倾斜
  • matrix() - 矩阵变换

注意事项

  1. 使用will-change: transform;提示浏览器优化
  2. 避免滥用,过多的合成层会增加内存消耗
  3. 2D变换比3D变换内存占用更少
  4. 动画结束后考虑移除transform属性,避免长期占用GPU内存

实现理想

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐