页面重绘重排

1、重绘(Repaint)
重绘是一个元素外观的改变所触发的浏览器行为,例如改变outline、背景色等属性。浏览器会根据元素的新属性重新绘制,
使元素呈现新的外观。重绘不会带来重新布局,所以并不一定伴随重排。

2、重排(Reflow)
渲染对象在创建完成并添加到渲染树时,并不包含位置和大小信息。计算这些值的过程称为布局或重排

"重绘"不一定需要"重排",比如改变某个网页元素的颜色,就只会触发"重绘",不会触发"重排",因为布局没有改变。
但是,"重排"必然导致"重绘",比如改变一个网页元素的位置,就会同时触发"重排"和"重绘",因为布局改变了。

3、常见的触发重排的操作
Reflow 的成本比 Repaint 的成本高得多的多。DOM Tree 里的每个结点都会有 reflow 方法,
一个结点的 reflow 很有可能导致子结点,甚至父点以及同级结点的 reflow。在一些高性能的电脑上也许还没什么,
但是如果 reflow 发生在手机上,那么这个过程是非常痛苦和耗电的。

所以,下面这些动作有很大可能会是成本比较高的。
当你增加、删除、修改 DOM 结点时,会导致 Reflow , Repaint。
当你移动 DOM 的位置
当你修改 CSS 样式的时候。
当你 Resize 窗口的时候(移动端没有这个问题)
当你修改网页的默认字体时。
获取某些属性时
注:display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,
因为没有发现位置变化。

4、注意
当你请求向浏览器请求一些 style信息的时候,就会让浏览器flush队列,比如:

(1)offsetTop, offsetLeft, offsetWidth, offsetHeight
(2)scrollTop/Left/Width/Height
(3)clientTop/Left/Width/Height
(4)width,height

当你请求上面的一些属性的时候,浏览器为了给你最精确的值,需要flush队列,
因为队列中可能会有影响到这些值的操作。即使你获取元素的布局和样式信息跟最近的布局信息差不多,
浏览器都会强行刷新渲染队列。


5、优化
(1)将多次改变样式属性的操作合并成一次操作
(2)将需要多次重排的元素,position属性设为absolute或fixed,
这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
(3)由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。
如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。这样只在隐藏和显示时触发2次重排。

转载于:https://www.cnblogs.com/momo798/p/6368396.html

### 浏览器重排的区别及其对性能的影响 #### 定义 重排(Reflow)是指当 DOM 的变化影响到元素的几何信息时,浏览器需要新计算这些元素的位置和尺寸,并将它们放置在页面上的正确位置的过程[^4]。这种行为通常涉及整个文档树或者部分子树的新布局。 与此不同的是(Repaint),它指的是当某个元素的外观发生变化但并未对其布局造成任何影响的时候所发生的视觉更新过程[^2]。比如更改了颜色、背景图像或者其他仅限于表现层面而不触及空间结构特性的属性。 #### 触发条件对比 - **重排**会被多种情况引发,其中包括但不限于调整窗口大小、滚动条操作、动态添加删除节点以及直接访问某些特定 CSS 属性如 `offsetWidth` 或者 `clientHeight` 等都会促使一次完整的回流发生[^5]。 - 对应之下,****则相对简单得多,只要那些不影响整体布局却改变了呈现效果的操作就会导致其产生,例如单纯变换字体样式或是透明度等级之类的小范围变动即可满足这一前提[^1]. #### 性能成本考量 由于每次执行重排都可能牵涉大量复杂的运算工作量——尤其是针对大型复杂网站而言更是如此;因此相较于单纯的来说往往消耗更多资源时间开销巨大许多倍数级差异明显可见[^3].而且值得注意的一点在于每当经历了一次全面意义上的重排之后紧接着不可避免地也会伴随至少一轮相应的局部乃至全局范围内不同程度规模下的刷新动作即所谓的"连锁反应",这无疑进一步加剧了原本就已十分沉的压力负担程度. ```javascript // 避免频繁触发布局计算的例子 let widthSum = 0; const elements = document.querySelectorAll('.item'); for (let i = 0; i < elements.length; ++i) { const element = elements[i]; // 不要在循环内部多次读取 offsetWidth 这样的布局属性 widthSum += element.offsetWidth; // 此处可能会触发不必要的 reflow } console.log(`Total Width: ${widthSum}`); ``` 上述代码片段展示了如何不当处理可能导致额外且无谓的重排风险增加情形之一例证说明而已并非唯一途径存在其他众多相似场景同样需要注意规避以免损害最终用户体验质量下降等问题出现.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值