回流(reflow)和重绘(repaint)
一、粗略了解浏览器渲染机制
- 浏览器采用的是流式布局: 流式布局:块级元素独占一行,行内元素在一行中从左到右依次排列。
- 浏览器会将html解析成DOM树,将css解析成CSSOM树。把DOM树和CSSOM树结合,生成render树。
- 有了render树,浏览器就可以根据render树来计算每个节点的几何信息(位置和大小),最后把元素渲染到页面上。
二、回流(reflow)
概述:回流也叫重排,回流就是当render树中的一部分因为元素的尺寸、位置或内容的变化而需要重新构建。
- 页面首页渲染
- 浏览器窗口大小变化
- 内容变化导致大小尺寸变化
- 添加或删除节点
- 激活css伪类(例如:hover)
- 改变元素位置,例如:margin、padding、border等
三、重绘(repaint)
概述:当render树中的一部分因为元素的样式变化而需要重新构建,但元素的位置和尺寸没有变化。
- 改变元素外观属性,例如:color、background-color、visibility、outline等
四、性能影响
- 渲染速度变慢:回流和重绘操作都需要消耗一定的计算资源。尤其是回流,由于涉及到页面布局的重新计算,其开销相对较大。因此,当页面频繁触发回流和重绘时,会导致页面的渲染速度变慢,从而影响用户的体验。
- 页面闪烁和卡顿:当浏览器进行回流和重绘操作时,页面可能会出现闪烁或卡顿的现象。这是因为浏览器在重新渲染页面时,会先清空原有的内容,然后再重新绘制。这个过程可能导致用户看到页面的短暂变化或停顿,尤其是在性能较低的设备或复杂的页面上。
- 资源消耗:频繁的回流和重绘操作不仅会导致CPU和内存的消耗增加,还可能引发其他资源的过度使用,如电池续航时间的减少等。
五、优化措施
- 减少DOM操作:避免不必要的DOM读写操作,可以缓存常用DOM对象到变量中,以减少直接访问DOM的次数。
- 利用CSS优化:尽量使用CSS动画代替JavaScript动画,因为CSS动画在浏览器层面进行优化,通常比JavaScript动画性能更好。同时,通过优化CSS选择器的性能,减少样式计算的开销。
- 批量修改:如果需要对多个元素进行样式修改或DOM操作,尽量将其合并成一次操作,以减少回流和重绘的次数。
- 使用请求动画帧(requestAnimationFrame):这个函数可以在浏览器的下一次重绘之前执行代码,从而确保动画的流畅性,并减少不必要的回流和重绘。
通过以上优化措施,可以有效地减轻回流和重绘对网页性能的影响,提升用户体验。