如何理解回流和重绘?
什么是回流?
当我们对DOM的修改引发了DOM几何尺寸的变化(比如修改元素的宽高、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性,然后再将计算结果绘制出来
- 全局范围:从根节点html开始对整个渲染树进行重新布局
- 局部范围:对渲染树的某一个渲染对象进行重新布局
什么是重绘?
当我们对DOM的修改导致了样式的变化(color或background),却并未影响其几何属性时,浏览器不需要重新计算元素的几何属性、直接为该元素绘制新的样式,这里就仅仅触发了重绘
回流必将引起重绘,重绘不一定引起回流
回流的触发时机?
当页面布局和几何信息发生变化的时候,就需要回流,以下这些情况就是触发回流的:
- 元素位置的变化
- 元素尺寸的变化(包括外边距、内边距、边框大小、高度和宽度等)
- 添加或删除一个可见的DOM元素
- 页面一开始渲染的时候(这不可避免)
- 浏览器的窗口尺寸变化
拓展一下:
- 获取一些特定属性的值(会触发回流): offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、 clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle
重绘触发时机?
触发回流一定触发重绘,以下这些就是触发重绘的例子:
- 颜色的修改
- 文本方向的修改
- 阴影的修改 例如下面这些:
- 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
如何减少回流和重绘?
- 如果想设定元素的样式,通过改变元素的clas类名(尽可能在DOM树的最里层)
- 避免设置多项内联样式
- 应用元素的动画,使用position属性的fixed值或absoulte
- 避免使用table布局,table中每个元素的大小以及内容的改动,都会导致整个table的重新计算
- 对于那些复杂的动画,对其设置position:fixed/absoulte,尽可能地使元素脱离文档流。从而减少对其它元素地影响
- 使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流和重绘
- 避免使用css的javascript表达式
对于回流和重绘的一些具体优化建议大家可以参考这篇文章:回流和重绘 - 掘金 (juejin.cn)