浏览器的回流(重排)与重绘(Reflow & Repaint)

浏览器的回流(重排)与重绘(Reflow & Repaint)
最新回答
死在新鲜感

2021-04-10 09:49:00

浏览器的回流(Reflow)与重绘(Repaint)

一、回流 (Reflow)

定义:会引起DOM树结构变化,页面布局变化的行为叫回流,且回流一定伴随重绘。

会导致回流的操作

  • 页面首次渲染
  • 添加或者删除可见的DOM元素
  • 元素位置改变
  • 元素尺寸改变(边距、填充、边框、高度和宽度)
  • 内容改变(比如文本改变或者图片大小改变而引起的计算值宽度和高度改变)
  • 浏览器窗口尺寸改变(resize事件发生时)

二、重绘 (Repaint)

定义:只是样式的变化,不会引起DOM树变化,页面布局变化的行为叫重绘,且重绘不一定会伴随回流。

会导致重绘的操作

  • 改变字体
  • 增加或者移除样式表
  • 内容变化(input框输入文字)
  • 激活css伪类(例如 :hover)
  • 计算offsetWidth、offsetHeight属性(浏览器的可见高度)
  • 设置style属性的值(除了影响布局的样式属性,如width、height、margin等,这些会导致回流)

注意:回流一定伴随着重绘,所以上述回流的行为都会导致重绘。除此之外,修改背景颜色、字体颜色等不影响布局的行为都只引发重绘。

三、怎么减少回流与重绘

为了减少浏览器的回流与重绘,提高页面性能,可以采取以下措施:

  1. DOM的增删行为

    避免频繁操作DOM,可以创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。

  2. 几何属性的变化

    避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。

  3. 元素位置的变化

    对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

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

    避免频繁读取会引发回流的属性(例如:scrollTop、scrollLeft、scrollWidth、offsetTop、offsetLeft、offsetWidth、offsetHeight之类的属性),如果确实需要多次使用,就用一个变量缓存起来。

  5. 表格布局

    尽量避免使用表格布局,因为当表格的td宽度不统一时,为了统一宽度,会导致前几行的td回流重新计算宽度,这是个很耗时的事情。

四、总结

  • 回流必将引起重绘,重绘不一定会引起回流。
  • 在进行页面优化时,要特别注意减少回流与重绘的次数,以提高页面的渲染性能。

面试重点

  1. display:none 与 visibility:hidden

    display:none 会导致元素脱离文档流,引起回流+重绘。

    visibility:hidden 只是让元素不可见,但仍在文档流中,只会引起重绘。

  2. 性能优化

    在进行DOM操作时,尽量合并多次操作为一次操作。

    避免频繁读取和修改会引起回流与重绘的属性。

    使用CSS3硬件加速技术(如transform、opacity等)来减少回流与重绘的次数。