浏览器的回流和重绘

1,307 阅读4分钟

引言

在讨论浏览器的回流和重绘之前,我们首先要知道浏览器的渲染过程(即浏览器是怎么将你在浏览器页面上看到的东西给渲染出来的),这对我们理解浏览器的重绘与回流有很大帮助,否则看完你可能还是感觉云里雾里(╯﹏╰),来吧让我们开始学习吧---٩(๑^o^๑)۶

浏览器的渲染过程

在你打开一个网页的时候,浏览器做了什么呢?请看下图

从图中,我们可以了解到,浏览器渲染过程如下:

  1. 解析HTML,生成DOM树,解析CSS,生成CSSOM树
  2. 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
  3. 回流(Layout):根据生成的渲染树,进行回流,得到节点的几何信息(位置,大小)
  4. 重绘(Painting):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  5. Display:将像素发送给GPU,展示在页面上

为构建渲染树,浏览器大体上完成了下列工作:

  1. 从 DOM 树的根节点开始遍历每个可见节点。
  2. 对于每个可见的节点,找到CSSOM树中对应的规则,并应用它们。
  3. 根据每个可见节点及对应的样式,组合生成渲染树。

既然提到了可见节点,那必然就还有不可见节点,那么什么是可见节点?什么是不可见节点呢?、这里我来向大家简单解释一下。

我们所见到的节点基本都是可见节点,所有不可见节点都是可见节点,那么与其记可见节点我们不妨来记不可见节点, 不可见节点有:

  • 一些不会渲染输出的节点,比如script、link等。
  • 一些通过css进行隐藏的节点。比如display:none。

注意: 利用visibilityopacity隐藏的节点,还是会显示在渲染树上的。只有display:none的节点才不会显示在渲染树上。 

回流(Reflow)

回流也被称为重构、重排

概念:当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流

tipe:每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的,因为要构建渲染树

触发条件:渲染树中的一部分(或全部)元素的规模尺寸,布局,隐藏等发生改变,重新渲染DOM树,发生回流。具体情况

  1. 页面一开始渲染的时候(无法避免)
  2. 添加或删除可见的DOM元素
  3. 元素的位置发生变化
  4. 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  5. 内容发生变化(文本变化或图片被另一个不同尺寸的图片所替代等)
  6. 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

重绘(Repaint)

概念: 当渲染树中元素样式的改变并不影响它在文档流中的位置时(不影响布局),比如colorbackground-colorvisibility等,浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘**。

换句话来说 ,重绘就是将渲染树节点转换为屏幕上的实际像素,不涉及重新布局阶段的位置与大小计算。 重绘跳过了生成布局树和建图层树的阶段,直接生成绘制列表,然后继续进行分块、生成位图等后面一系列操作。

由此可以理解,回流一定会触发重绘,而重绘不一定会回流

优化

在了解完重回与回流后可以明白,重绘和回流是十分影响浏览器性能的,那么在我们实际开发中该如何避免呢,笔者这里给出以下建议

1. 限制回流和重绘的范围

2. 避免频繁使用style,而是采用修改class的方式

3. 对于resize、scroll等进行防抖、节流处理

4. 避免使用table布局,可能很⼩的⼀个⼩改动会造成整个table的重新布局

既然都看到这里了,确定不点个赞吗d(ŐдŐ๑) 如果对你有帮助的话,记得点赞加关注鸭!您的关注和点赞是对我最大的支持!