Reflow(回流)和Repaint(重绘)

理解Reflow与Repaint
本文详细解释了网页渲染过程中的关键概念Reflow与Repaint,包括它们的区别、触发条件及如何优化,以提高网页性能。

首先我们要明白的是,页面的显示过程分为以下几个阶段:

1、生成DOM树(包括display:none的节点)

2、在DOM树的基础上根据节点的集合属性(margin,padding,width,height等)生成render树(不包括display:none,head节点,但是包括visibility:hidden的节点)

3、在render树的基础上继续渲染颜色背景色等样式

Reflow:当render树的一部分或者全部因为大小边距等问题发生改变而需要重建的过程,叫做回流

reflow会影响到dom的结构渲染,同时会触发repaint,他会改变他本身与所有父辈元素(祖先),这种开销是非常昂贵的,导致性能下降是必然的,页面元素越多效果越明显。

Repaint(重绘):当诸如颜色背景等不会引起页面布局变化,而只需要重新渲染的过程叫做重绘

repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,不会影响到dom结构渲染。

通过上述定义,可以很明显看出,重绘的代价要比回流小,毕竟重绘只涉及样式的改变,不涉及到布局。


什么情况下会触发浏览器的repaint/reflow?

1.DOM元素的添加、修改(内容)、删除( Reflow + Repaint)
2.仅修改DOM元素的字体颜色(只有Repaint,因为不需要调整布局)
3.应用新的样式或者修改任何影响元素外观的属性
4.Resize浏览器窗口、滚动页面
5.读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、 scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE))
6.改变字体大小
7.添加、删除样式表
8.内容的改变,如用户在输入框中写字
9.激活伪类
10.设置style属性


如何避免repaint/reflow?

1.先将元素从document中删除,完成修改后再把元素放回原来的位置
2.将元素的display设置为”none”,完成修改后再把display修改为原来的值*
3.如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入document
  var fragment = document.createDocumentFragment();
  fragment.appendChild(document.createTextNode(‘keenboy test 111’));
  fragment.appendChild(document.createElement(‘br’));
  fragment.appendChild(document.createTextNode(‘keenboy test 222’));
  document.body.appendChild(fragment);
4.集中修改样式**  
(1)尽可能少的修改元素style上的属性  
(2)尽量通过修改className来修改样式  
(3)通过cssText属性来设置样式值
    element.style.width=”80px”; //reflow
    element.style.height=”90px”; //reflow
    element.style.border=”solid 1px red”; //reflow
    以上就产生多次reflow,调用的越多产生就越多
    element.style.cssText=”width:80px;height:80px;border:solid 1px red;”; //reflow
(4)缓存Layout属性值
    var left=elem.offsetLeft; 多次使用left也就产生一次reflow   
(5)设置元素的position为absolute或fixed
    元素脱离标准流,也从DOM树结构中脱离出来,在需要reflow时只需要reflow自身与下级元素   
(6)避免使用expression,他会每次调用都会重新计算一遍(包括加载页面) 
(7)尽量不要用table布局
    table元素一旦触发reflow就会导致table里所有的其它元素 reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围

### 浏览器渲染中的回流 #### 回流Reflow回流是指当 DOM 的结构或元素的几何属性(如大小、位置等)发生变化时,浏览器需要新计算这些元素的位置尺寸,并更新整个页面布局的过程。这一过程通常涉及多个节点的新计算以及可能引发后续子树的调整[^1]。 例如,如果动态改变了某个元素的高度或者宽度,或者是隐藏了一个可见的元素,则会触发回流操作。每次回流都会带来一定的性能开销,尤其是复杂的布局场景下更为显著[^5]。 #### Repaint) 相比之下,指的是由于某些视觉样式的更改而不需要改变文档流的情况下发生的制行为。比如颜色的变化、背景图片替换等情况只会导致像素级别的刷新而不影响整体布局结构[^3]。 需要注意的是,尽管单独来看似乎比回流轻量级一些,但如果频繁发生也可能累积成较大的性能瓶颈[^2]。 #### 主要区别 | 特性 | 回流 | | |--------------|-------------------------------|-------------------------| | **定义** | 布局变化引起的新计算 | 只有外观上的变动 | | **触发条件** | 修改了影响布局的因素 | 改变了不影响布局的样式 | | **范围** | 影响较大 | 较小 | | **频率控制** | 应尽量减少 | 同理需加以管理 | 为了提升网页加载速度并改善用户体验,在开发过程中应当采取措施来降低不必要的回流事件的发生几率。可以通过批量处理DOM变更动作、使用虚拟dom技术等方式实现优化目的;另外还可以考虑采用GPU加速特性明显的 CSS 属性如 `transform` `opacity`, 这些不会引起常规意义上的reflow/repaint流程而是交由更高效的图形处理器完成相应工作[^4]。 ```javascript // 减少回流的一个例子:先移除元素再做多次修改最后放回去 let parentElement = document.getElementById('parent'); let childToModify = document.createElement('div'); childToModify.style.width = '200px'; childToModify.style.height = '200px'; childToModify.style.backgroundColor = '#ff0000'; parentElement.appendChild(childToModify); ``` 上述代码展示了如何通过创建新节点而非直接操作现有DOM节点的方式来避免连续性的回流问题。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值