什么是回流和重绘,回流和重绘有哪些区别
什么是回流,什么是重绘
首先我们需要了解下浏览器的渲染过程
- 解析
HTML
,生成DOM
树,解析CSS
,生成CSSOM
树- 将
DOM
树 和CSSOM
树结合,生成渲染树(Render Tree
)- 渲染树的每个元素包含的内容都是计算过的,它被称之为布局(
layout
)。浏览器使用一种流式处理的方法,只需要一次绘制操作就可以布局所有的元素- 将渲染树的各个节点绘制到屏幕上,这一步被称为绘制(
painting
)
- 可简化为以下流程:
1. 解析html和css —> 2. 构建dom树和cssom树 —> 3. 构建渲染树(render tree) —> 4. 布局render树(layout) —> 5. 绘制render树(painting)
- 什么是回流(
reflow
)
回流(reflow
)又称重排,当浏览器发现布局(layout
)发生了变化,这个时候就需要倒回去重新渲染,这个过程叫 回流(reflow
)。回流几乎是无法避免的,因为只要用户进行了交互操作,就会发生页面的一部分重新渲染。 - 什么是重绘(
repaint
)
重绘(repaint
)则是当我们改变某个元素的背景色,文字颜色,边框颜色等不影响它周围或内部布局的属性是,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变。
注意:
display:none
会触发回流(reflow
)visibility:hidden
属性表示隐藏元素,元素任然占据着布局空间,并没有改变布局和几何尺寸,所以只会触发 重绘(repaint
)
回流和重绘的触发时机分别是什么
- 回流触发时机
当元素的位置或者几何尺寸发生改变时会触发回流,现代浏览器会对回流做优化,它会等到足够数量的变化发生,再做一次批处理回流。例如以下操作会触发回流:- 页面的第一次渲染(初始化)
DOM
树的变化(如:增删节点)Render
树的变化(如:padding
改变)- 浏览器窗口的尺寸变化
resize
fontsize
的变化- 获取元素的某些属性:浏览器为了获取正确的最新属性值也会提前触发回流,这些属性包括:
offsetLest、 offsetTop、 offsetWidth、 offsetHeight、 scrollTop/Left/Width/Height、clientTop/Left/Width/Height
、 调用了getComputedStyle()
。
- 重绘触发时机
背景色、颜色的改变等会引起重绘(repaint
)
回流和重绘的区别是什么
- 回流和重绘的触发条件不同
- 回流是在
DOM
结构发生变化时触发的,例如添加、删除或修改元素、修改元素的位置或大小等。 - 重绘是在元素的样式属性发生变化时触发的,例如修改元素的颜色、背景、边框等。
- 回流是在
- 回流的代价比重绘高
- 由于回流需要重新计算元素的位置和大小,所以它的代价比较高。
- 重绘只需要重新绘制元素的样式,所以代价相对较低。
- 因此,在性能优化中,我们应该尽量减少回流的次数,以提高网页的渲染性能。
- 回流会引起重绘,但重绘不一定会引起回流
- 当一个元素的样式属性发生变化时,浏览器会首先进行重绘,然后根据新的样式属性重新计算元素的位置和大小。
- 如果有必要的话,还会触发其他元素的回流。所以,回流是重绘的必要条件,但重绘不一定会引起回流。
开发过程中如何针对回流和重绘做优化
为了优化性能,我们需要减少回流、重绘的触发次数
- 用
transform
做形变和位移可以减少回流 - 避免组个修改节点样式,尽量一次性修改
- 可以将需要多次修改的
DOM
元素设置display:none
,操作完再显示(因为隐藏元素不在render
树内,因此修改隐藏元素不会触发回流重绘) - 避免多次读取某些属性
- 通过绝对位移将复杂的节点元素脱离文档流,形成新的
Render Layer
,降低回流成本