重绘和回流

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

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

何时发生:

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))

如何避免:

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. 集中修改样式
  4.1尽可能少的修改元素style上的属性
  4.2尽量通过修改className来修改样式
  4.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.4缓存Layout属性值
    var left=elem.offsetLeft; 多次使用left也就产生一次reflow
  4.5设置元素的position为absolute或fixed
    元素脱离标准流,也从DOM树结构中脱离出来,在需要reflow时只需要reflow自身与下级元素
  4.6尽量不要用table布局
    table元素一旦触发reflow就会导致table里所有的其它元素 reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围
  4.7避免使用expression,他会每次调用都会重新计算一遍(包括加载页面)

参考:

Yahoo! 性能工程师 Nicole Sullivan 在最新的文章 《Reflows & Repaints: CSS Performance making your JavaScript slow?》

转载于:https://www.cnblogs.com/alicePanZ/p/4796412.html

### 回流在前端开发中的区别及影响性能的因素 #### 1. 定义与触发场景 - **回流(Reflow)** 是指当 DOM 树中的元素尺寸、布局、结构或内容发生改变时,浏览器需要新计算这些元素的几何属性,并更新页面的渲染树。这种操作通常涉及多个元素,甚至整个文档的新布局[^1]。例如,修改元素的宽高、添加或删除 DOM 节点、隐藏或显示某些元素等都会触发回流。 - **(Repaint)** 是指当元素的外观发生变化但不影响其布局时,浏览器只需制该元素以反映变化。这通常包括颜色、背景、边框样式等视觉属性的更改[^2]。例如,改变一个元素的背景颜色或透明度不会导致布局变化,因此只会触发。 #### 2. 性能影响 - 回流的影响范围更广,因为它涉及到布局的新计算,可能会波及到父元素子元素,甚至整个页面的新布局[^3]。频繁的回流会显著降低页面性能,尤其是在复杂布局中。 - 虽然只涉及视觉上的更新,但如果频繁发生,尤其是在动画或动态交互中,仍然会对性能造成压力。相比回流的开销通常较小,但两者往往是相伴发生的[^4]。 #### 3. 触发回流的操作 以下操作可能会触发回流: - 修改 DOM 元素的几何属性(如宽度、高度)。 - 添加或删除可见的 DOM 元素。 - 隐藏或显示某些元素(使用 `display: none`)。 - 获取某些布局相关的属性(如 `offsetWidth`、`offsetHeight` 等)[^5]。 #### 4. 触发的操作 以下操作可能会触发: - 修改元素的颜色、背景、字体样式等视觉属性。 - 改变元素的透明度或可见性(使用 `visibility: hidden`)。 - 动画效果中的非布局属性变化。 #### 5. 优化技巧 为了减少回流对性能的影响,可以采取以下措施: - **批量操作 DOM**:尽量将多次 DOM 操作合并为一次,例如通过创建文档片段(DocumentFragment)来减少回流次数[^5]。 - **缓存布局属性**:如果需要多次读取某些布局相关的属性(如 `offsetWidth`),应将其值缓存到变量中,避免反复触发回流。 - **使用 CSS 脱离文档流**:对于动画效果,使用 `position: absolute` 或 `position: fixed` 将元素从正常文档流中移除,从而减少对其他元素布局的影响。 - **避免表格布局**:表格布局的小改动可能会导致整个表格的新布局,因此尽量避免使用表格进行复杂布局。 ```python # 示例代码:批量操作 DOM document_fragment = document.createDocumentFragment() for i in range(100): new_element = document.createElement("div") new_element.textContent = f"Item {i}" document_fragment.appendChild(new_element) container.appendChild(document_fragment) # 一次性插入所有元素 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值