如何理解回流和重绘2

如何理解回流和重绘2
最新回答
薄荷糖味的吻

2023-11-01 22:51:19

回流(Reflow)和重绘(Repaint)是浏览器渲染过程中的两个关键概念,理解它们对优化网页性能至关重要。

  • 回流:当Render Tree中部分或全部元素的尺寸、结构或某些属性发生改变时,浏览器需要重新计算元素在文档中的位置和大小,并重新渲染部分或全部文档。回流会导致重绘,因为元素的视觉表现需要更新。
  • 重绘:当元素的样式改变不影响其在文档流中的位置时(如颜色、背景色等),浏览器会重新绘制该元素。重绘不一定会导致回流,因为元素的布局和尺寸没有变化。

回流和重绘的关系:回流必将引起重绘,因为元素的视觉表现需要更新;但重绘不一定会引起回流,因为元素的布局和尺寸没有变化。

导致回流的操作

  • 页面首次渲染。
  • 浏览器窗口大小发生改变。
  • 元素尺寸或位置发生改变。
  • 元素内容变化(如文字数量或图片大小等)。
  • 元素字体大小变化。
  • 添加或删除可见的DOM元素。
  • 激活CSS伪类(如:hover)。
  • 查询某些属性或调用某些方法(如clientWidth、offsetHeight等)。

导致重绘的操作

  • 元素样式的改变不影响其在文档流中的位置(如color、background-color、visibility等)。

性能影响

  • 回流比重绘的代价更高,因为它涉及重新计算布局和渲染。
  • 现代浏览器会对频繁的回流或重绘操作进行优化,通过维护一个队列来批量处理这些操作。

如何避免不必要的回流和重绘

  • CSS方面

    避免使用table布局,因为table元素的渲染可能需要多次计算。

    尽可能在DOM树的最末端改变class,以减少回流的范围。

    避免设置多层内联样式,以减少样式计算的时间。

    将动画效果应用到position属性为absolute或fixed的元素上,使它们脱离文档流,减少回流的影响。

    避免使用CSS表达式(如calc()),因为它们可能导致频繁的样式计算。

  • JavaScript方面

    避免频繁操作样式,最好一次性重写style属性或更改class属性。

    避免频繁操作DOM,可以使用documentFragment来批量处理DOM操作。

    可以先为元素设置display: none,操作结束后再显示它,因为在display: none的元素上的操作不会引发回流和重绘。

    避免频繁读取会引发回流/重绘的属性,如果需要多次使用,可以用变量缓存起来。

    对具有复杂动画的元素使用绝对定位,使其脱离文档流,减少回流的影响。