阅读 40

深入浅出谈重绘和回流

1、重绘

由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘。

2、回流

当DOM节点中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流。

3、重绘不一定引起回流,而回流一定会引起重绘。

会导致回流的操作:

  • 页面的首次刷新
  • 浏览器的窗口大小发生改变
  • 元素的大小或位置发生改变
  • 改变字体的大小
  • 内容的变化(如:input框的输入,图片的大小)
  • 激活css伪类 (如::hover)
  • 脚本操作DOM(添加或者删除可见的DOM元素)

一些常用且会导致回流的属性和方法:

  • clientWidth、clientHeight、clientTop、clientLeft
  • offsetWidth、offsetHeight、offsetTop、offsetLeft
  • scrollWidth、scrollHeight、scrollTop、scrollLeft
  • scrollIntoView()、scrollIntoViewIfNeeded()
  • getComputedStyle()
  • getBoundingClientRect()
  • scrollTo()

4、如何将回流的影响降到最低:

  • 如果想设定元素的样式,通过改变元素的 class 名(尽可能在 DOM 树的最末端)
  • 避免设置多项内联样式
  • 应用元素的动画,使用 position 属性的 fixed 值或 absolute 值
  • 权衡平滑和速度
  • 避免使用table布局
  • 避免使用CSS的Javascript表达式(仅IE浏览器)
  • 避免使用CSS表达式(列如:calc())

5、怎么减少回流

说了这么多,我们也知道了,回流要重新构建DOM树,渲染树也得重新渲染,很麻烦,哪么哪些行为会引起回流,怎么去避免呢?

1.DOM的增删行为

比如你要删除某个节点,给某个父元素增加子元素,这类操作都会引起回流。如果要加多个子元素,最好使用documentfragment。

2.几何属性的变化

比如元素宽高变了,border变了,字体大小变了,这种直接会引起页面布局变化的操作也会引起回流。如果你要改变多个属性,最好将这些属性定义在一个class中,直接修改class名,这样只用引起一次回流。

3.元素位置的变化

修改一个元素的左右margin,padding之类的操作,所以在做元素位移的动画,不要更改margin之类的属性,使用定位脱离文档流后改变位置会更好。

4.获取元素的偏移量属性

例如获取一个元素的scrollTop、scrollLeft、scrollWidth、offsetTop、offsetLeft、offsetWidth、offsetHeight之类的属性,浏览器为了保证值的正确也会回流取得最新的值,所以如果你要多次操作,最取完做个缓存。

5.页面初次渲染

这样的回流无法避免

6.浏览器窗口尺寸改变

resize事件发生也会引起回流。

文章分类
前端
文章标签