重排、重绘及合成

重排、重绘及合成

一、重排

定义:部分渲染树(或者整个渲染树)需要重新分析并且节点尺⼨需要重新计算,表现为重新⽣成布局,重新排列元素。例如改变元素位置或大小等。

在这里插入图片描述

触发条件
  • 添加、删除、更新DOM节点
  • 通过display: none隐藏⼀个DOM节点
  • 移动或者给⻚⾯中的DOM节点添加动画
  • 添加⼀个样式表,调整样式属性
  • ⽤户⾏为,例如调整窗⼝⼤⼩,改变字号,或者滚动。
  • 页面渲染初始化(无法避免)
优化方案
  • 尽量不要在布局信息改变时做查询(会导致渲染队列强制刷新)。
  • 集中改变样式 。
// 判断是否是⿊⾊系样式 
const theme = isDark ? 'dark' : 'light' 64
// 根据判断来设置不同的
class ele.setAttribute('className', theme)
  • 避免使用table。
  • 使用fragment元素(createDocumentFragment)

我们可以通过createDocumentFragment创建⼀个游离于DOM树之外的节点,然后在此节点上批量操作,最后插⼊DOM树中,因此只触发⼀次重排

var fragment = document.createDocumentFragment()
for (let i = 0; i<10; i++){ 
  let node = document.createElement("p")
  node.innerHTML = i 
  fragment.appendChild(node)
}
document.body.appendChild(fragment)
  • 使用采用虚拟DOM的库,如Vue,React

  • 提升为合成层

    提升为合成层的优点:

    • 合成层的位图,会交由 GPU 合成,⽐ CPU 处理要快

    • 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层

    • 对于 transform 和 opacity 效果,不会触发 layout 和 paint

提升合成层的最好⽅式是使⽤ CSS 的 will-change 属性(为web开发者提供了一种告知浏览器该元素会有哪些变化的方法,这样浏览器可以在元素属性真正发生变化之前提前做好对应的优化准备工作,这个最好用完后就释放):

#target { 
  will-change: transform;
}

二、重绘:

定义: 由于节点的⼏何属性发⽣改变或者由于样式发⽣改变,例如改变元素背景⾊时,屏幕上的部分内容需要更新,表现为某些元素的外观被改变 。

在这里插入图片描述

触发条件
  • background属性(background,background-color,background-image,background-position,background-repeat,background-size)
  • outline属性(outline,outline-color,outline-style)
  • box-shadow属性
  • border属性(border-style,border-radius)
  • 通过visibility: hidden隐藏⼀个DOM节点
优化方案
  • 合并多次操作

三、合成

定义: 更改一个既不要布局也不要绘制的属性,渲染引擎将跳过布局和绘制,只执行后续的合成操作,我们把这个过程叫做合成。比如我们使用了 CSS 的 transform 来实现动画效果,这可以避开重排和重绘阶段,直接在非主线程上执行合成动画操作。这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。

在这里插入图片描述

触发条件
  • will-change
  • translate3dtranslateZ
  • 整个图层的几何变换,透明度变换,阴影。
四、总结

『重绘』不⼀定会出现『重排』,『重排』必然会出现『重绘』。

<think>好的,我现在需要回答用户关于“重排有什么区别”的问题。首先,我应该回忆一下这两个概念的定义和它们在浏览器渲染过程中的作用。 重排(Reflow)应该是指浏览器计算元素的位置和几何属性,新构建页面的布局。当元素的尺寸、位置等发生变化时,浏览器需要新计算其他元素的位置,这可能会导致整个或部分页面布局的新计算。这个过程可能比较消耗性能,特别是在复杂的页面结构中。 (Repaint)则是在元素的外观发生变化,但不影响布局的情况下发生的。比如改变颜色、背景等样式时,浏览器只需要制受影响的部分,而不需要新计算布局。因此,的性能开销比重排小。 接下来,我需要确定这两个概念在浏览器渲染流程中的位置。通常,浏览器的渲染流程包括解析HTML生成DOM树,解析CSS生成CSSOM树,合并成渲染树,然后进行布局(Layout,即重排),最后制(Paint,即)。因此,重排发生在布局阶段,而发生在制阶段。 然后,我需要考虑触发重排的常见操作。例如,改变元素的宽度、高度、位置(如left、top)等会触发重排,而改变颜色、背景、边框样式等则只会触发。不过需要注意的是,某些操作可能会同时触发两者,比如改变元素的宽度可能会导致重排,之后浏览器需要新的尺寸。 另外,现代浏览器可能会对连续的重排操作进行优化,比如将它们合并成一次操作。但作为开发者,仍然应该尽量减少不必要的重排,以提高页面性能。例如,使用CSStransform属性来做动画,而不是直接修改元素的top/left属性,因为transform通常不会触发重排,可以利用GPU加速,只触发。 还要提到如何避免不必要的重排的方法。比如,使用DocumentFragment进行多次DOM操作后一次性添加到文档中,或者将元素的display设置为none进行修改后再显示,这样修改过程不会触发多次重排。 可能需要举例说明两者的区别,比如修改元素的背景颜色只会导致,而修改元素的宽度会导致重排。此外,获取某些布局信息(如offsetWidth、scrollTop等)会强制浏览器触发重排以获取最新值,这可能会影响性能,特别是在循环中频繁读取这些属性。 最后,总结两者的区别:重排涉及布局变化,消耗较大;仅涉及外观变化,消耗较小。优化时应优先减少重排次数,避免强制同步布局,合理使用CSS属性。</think>(Repaint)和重排(Reflow)是浏览器渲染页面的两个核心机制,它们的区别主要体现在**触发条件**和**性能消耗**上: --- ### 一、本质区别 1. **重排(Reflow)** 浏览器需要**新计算元素的位置和尺寸**(布局阶段)。 - 触发条件:修改影响布局的属性(如宽度、高度、位置、字体大小等) - 示例:`width`, `height`, `margin`, `padding`, `display: none`, `offsetHeight`等 2. **(Repaint)** 浏览器**仅制元素的视觉效果**(制阶段),不涉及布局变化。 - 触发条件:修改仅影响外观的属性(如颜色、背景、边框等) - 示例:`color`, `background`, `border-radius`, `visibility: hidden`等 --- ### 二、性能差异 | | 重排 | | |----------|-----------------------|---------------------| | **消耗** | 高(需新布局整棵树) | 低(仅局部制) | | **关系** | 重排必然引起 | 不一定触发重排 | --- ### 三、典型场景 1. **触发重排的操作** ```js element.style.width = "100px"; // 修改尺寸 element.style.left = "20px"; // 修改位置 element.classList.add("new-layout");// 添加影响布局的CSS类 ``` 2. **仅触发的操作** ```js element.style.color = "red"; // 修改颜色 element.style.backgroundColor = "#f00"; // 修改背景 ``` --- ### 四、优化建议 1. **避免频繁操作DOM** 使用 `DocumentFragment` 或虚拟DOM技术批量更新。 2. **优先使用CSS动画** 用 `transform` 和 `opacity` 实现动画(触发GPU加速,跳过重排)。 3. **读写分离** 避免在读取布局属性(如 `offsetWidth`)后立即修改样式,防止强制同步布局: ```js // 错误示例(触发多次重排) for (let i = 0; i < 100; i++) { element.style.width = i + "px"; // 写操作 console.log(element.offsetWidth);// 读操作,强制重排 } // 正确做法:先读后写 const width = element.offsetWidth; // 一次性读取 for (let i = 0; i < 100; i++) { element.style.width = width + i + "px"; // 批量写 } ``` 4. **隐藏元素再操作** 对需要大量修改的元素先设置 `display: none`,操作完成后再显示。 --- ### 五、流程图解浏览器渲染过程 ``` 1. 解析HTML → 生成DOM树 2. 解析CSS → 生成CSSOM树 3. 合并DOM+CSSOM → 渲染树(Render Tree) 4. 计算布局 → **重排(Reflow)** 5. 制像素 → **(Repaint)** 6. 合成图层 → 显示页面(Composite) ``` 通过理解重排的机制,开发者可以更高效地优化网页性能,尤其是在高频交互场景(如动画、滚动)中效果显著。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值