目录
2.除了浏览器的优化机制,我们还可以通过以下的方法来减少触发:
一、是什么
1.回流(reflow)
回流是指当页面的布局和几何属性发生改变时,浏览器需要重新计算元素的位置和大小,然后重新构建整个页面的布局树(Layout Tree)。这个过程涉及到对元素的尺寸、位置、盒模型等属性进行计算,然后确定元素在页面中的具体位置。回流会触发浏览器重新绘制页面的过程。
2.重绘(repaint)
重绘是指当页面的外观属性(如颜色、背景等)发生改变时,浏览器只需要重新绘制受影响的部分,而不需要重新计算布局。重绘不会改变元素的布局,只会更新元素的样式。重绘的过程是将新的样式应用到元素上,并重新绘制元素的外观。
3.区别
回流和重绘的区别在于是否需要重新计算布局。回流的成本比较高,因为它需要重新计算整个页面的布局树,而且会导致其他相关元素的重新布局。而重绘的成本相对较低,因为它只需要重新绘制受影响的部分,不需要重新计算布局。
二、如何触发
1.回流(reflow):
当页面布局和几何信息发生变化时就会触发回流:如
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
- 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代
- 页面一开始渲染的时候(这避免不了)
- 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
2.重绘(repaint):
由定义我们知道,触发回流一定会触发重绘,所以上面触发回流的情况也会触发重绘,除此自外还有如下:
-
颜色的修改
-
文本方向的修改
-
阴影的修改
三、如何减少触发
1.浏览器优化机制
由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。
当你获取布局信息的操作的时候,会强制队列刷新,如offsetTop
等方法都会返回最新的数据,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。
2.除了浏览器的优化机制,我们还可以通过以下的方法来减少触发:
- 如果想设定元素的样式,通过改变元素的
class
类名 (尽可能在 DOM 树的最里层) - 避免设置多项内联样式
- 应用元素的动画,使用
position
属性的fixed
值或absolute
值(如前文示例所提) - 避免使用
table
布局,table
中每个元素的大小以及内容的改动,都会导致整个table
的重新计算 - 对于那些复杂的动画,对其设置
position: fixed/absolute
,尽可能地使元素脱离文档流,从而减少对其他元素的影响 - 使用css3硬件加速,可以让
transform
、opacity
、filters
这些动画不会引起回流重绘 - 避免使用 CSS 的
JavaScript
表达式
四、附录
1.常见引起回流的属性和方法
- width
- height
- margin
- padding
- display
- border
- position
- overflow
- clientWidth
- clientHeight
- clientTop
- clientLeft
- offsetWidth
- offsetHeight
- offsetTop
- offsetLeft
- scrollWidth
- scrollHeight
- scrollTop
- scrollLeft
- scrollIntoView()
- scrollTo()
- getComputedStyle()
- getBoundingClientRect()
- scrollIntoViewIfNeeded()
2.常见引起重绘的属性和方法
- color
- border-style
- visibility
- background
- text-decoration
- background-image
- background-position
- background-repeat
- outline-color
- outline
- outline-style
- border-radius
- outline-width
- box-shadow
- background-size