引言
在讨论浏览器的回流和重绘之前,我们首先要知道浏览器的渲染过程(即浏览器是怎么将你在浏览器页面上看到的东西给渲染出来的),这对我们理解浏览器的重绘与回流有很大帮助,否则看完你可能还是感觉云里雾里(╯﹏╰),来吧让我们开始学习吧---٩(๑^o^๑)۶
浏览器的渲染过程
在你打开一个网页的时候,浏览器做了什么呢?请看下图
从图中,我们可以了解到,浏览器渲染过程如下:
- 解析HTML,生成DOM树,解析CSS,生成CSSOM树
- 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
- 回流(Layout):根据生成的渲染树,进行回流,得到节点的几何信息(位置,大小)
- 重绘(Painting):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
- Display:将像素发送给GPU,展示在页面上
为构建渲染树,浏览器大体上完成了下列工作:
- 从 DOM 树的根节点开始遍历每个可见节点。
- 对于每个可见的节点,找到CSSOM树中对应的规则,并应用它们。
- 根据每个可见节点及对应的样式,组合生成渲染树。
既然提到了可见节点,那必然就还有不可见节点,那么什么是可见节点?什么是不可见节点呢?、这里我来向大家简单解释一下。
我们所见到的节点基本都是可见节点,所有不可见节点都是可见节点,那么与其记可见节点我们不妨来记不可见节点, 不可见节点有:
- 一些不会渲染输出的节点,比如script、link等。
- 一些通过css进行隐藏的节点。比如display:none。
注意: 利用visibility和opacity隐藏的节点,还是会显示在渲染树上的。只有display:none的节点才不会显示在渲染树上。
回流(Reflow)
回流也被称为重构、重排
概念:当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流。
tipe:每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的,因为要构建渲染树
触发条件:渲染树中的一部分(或全部)元素的规模尺寸,布局,隐藏等发生改变,重新渲染DOM树,发生回流。具体情况:
- 页面一开始渲染的时候(无法避免)
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
- 内容发生变化(文本变化或图片被另一个不同尺寸的图片所替代等)
- 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
重绘(Repaint)
概念: 当渲染树中元素样式的改变并不影响它在文档流中的位置时(不影响布局),比如color、background-color、visibility等,浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘**。
换句话来说 ,重绘就是将渲染树节点转换为屏幕上的实际像素,不涉及重新布局阶段的位置与大小计算。 重绘跳过了生成布局树和建图层树的阶段,直接生成绘制列表,然后继续进行分块、生成位图等后面一系列操作。
由此可以理解,回流一定会触发重绘,而重绘不一定会回流
优化
在了解完重回与回流后可以明白,重绘和回流是十分影响浏览器性能的,那么在我们实际开发中该如何避免呢,笔者这里给出以下建议:
1. 限制回流和重绘的范围
2. 避免频繁使用style,而是采用修改class的方式
3. 对于resize、scroll等进行防抖、节流处理
4. 避免使用table布局,可能很⼩的⼀个⼩改动会造成整个table的重新布局
既然都看到这里了,确定不点个赞吗d(ŐдŐ๑) 如果对你有帮助的话,记得点赞加关注鸭!您的关注和点赞是对我最大的支持!