无需登录 数据私有 本地保存

DOM 重排/重绘触发器测试 - 性能影响可视化

32
0
0
0

DOM 重排/重绘触发器测试

性能影响可视化 · Performance Impact Visualizer

测试块:200 迭代:10
200
10
实时测试区域 就绪
性能摘要
0
重排操作次数
0
重绘操作次数
-
平均重排耗时
-
平均重绘耗时
-
重排/重绘耗时比(重排代价)
触发重排 (Reflow)
仅触发重绘 (Repaint)
强制同步重排 & 布局抖动
测试结果记录 共 0 条
# 操作名称 类型 平均耗时 最小 最大 触发 性能影响可视化
尚未执行测试,点击上方按钮开始
常见问题 & 知识点

重排(Reflow),也称为布局(Layout),是浏览器计算页面元素位置和尺寸的过程。当DOM结构、元素尺寸、位置、字体等影响布局的属性发生变化时,浏览器必须重新计算元素的几何属性。重排是一个代价高昂的操作,因为它会递归影响子元素和后续兄弟元素。触发重排的常见操作包括:修改 width/heightmargin/paddingfont-size、添加/删除DOM元素、修改 display 属性、读取 offsetHeight 等布局属性(强制同步重排)。

重绘(Repaint)是指元素外观改变但不影响布局时,浏览器重新绘制元素的过程。重绘不涉及布局计算,因此比重排快得多。触发重绘的操作包括:修改 colorbackground-colorbox-shadowborder-colorvisibilityoutline 等。

核心区别:重排必然触发重绘(因为布局变了需要重新画),但重绘不一定触发重排。因此优先使用只触发重绘的CSS属性可以显著提升性能。例如动画使用 transformopacity 而非 top/left

当JavaScript读取布局属性(如 offsetHeightoffsetWidthgetBoundingClientRect()scrollTop 等)时,如果之前有未应用的样式修改,浏览器必须立即同步执行重排以返回准确值。这被称为"强制同步重排"。在循环中交替读写是典型的布局抖动(Layout Thrashing)反模式,会严重拖慢页面性能。解决方法是先批量读取,再批量写入(Read-Then-Write模式),或使用 requestAnimationFrame

  • 批量修改DOM:使用 DocumentFragment 或先 display:none 再修改,最后显示。
  • 使用CSS类而非逐条修改样式:切换类名只触发一次重排,而逐条修改 element.style.xxx 可能触发多次。
  • 动画使用 transform 和 opacity:这两个属性在合成器线程处理,不触发重排/重绘。
  • 使用 will-change:提前告知浏览器哪些属性会变化,让浏览器做好准备。
  • 使用 CSS containment:contain: layout style paint 限制重排/重绘的影响范围。
  • 先读后写:避免在循环中交叉读取布局属性和修改样式。
  • 使用 requestAnimationFrame:将视觉更新合并到浏览器的渲染帧中。

以下CSS属性修改时仅触发重绘,不会触发重排:
colorbackground-colorbox-shadowborder-coloroutlineoutline-colorvisibilitytext-decorationbackground-image(仅颜色变化部分)、border-radius(不改变尺寸时)、opacity(合成器处理,甚至不触发重绘)。

使用这些属性做交互效果(如hover变色)性能更优。

浏览器渲染一个帧通常经历以下阶段:
JavaScript执行 → 样式计算(Style) → 布局/重排(Layout) → 绘制/重绘(Paint) → 合成(Composite)

CSS transformopacity 可以跳过布局和绘制阶段,直接在合成器线程处理,因此动画性能最佳。理解这个流水线有助于写出高性能的前端代码。