html中的回流、重绘

html-css04

html中的回流、重绘,第1张

重新渲染页面需要重新计算元素的几何大小和位置,这个计算的过程称之为回流。

元素更新属性,属性只影响元素的外观、风格而不影响布局的称之为重绘。

如 color 属性

回流一定会引起重绘,但是重绘不一定引起回流。

在HTML中,每个元素都可以理解成一个盒子,在浏览器解析过程中,会涉及到回流与重绘。

回流 :布局引擎会根据各种样式计算每个盒子在页面上的大小与位置。

在页面初始渲染阶段,回流不可避免的触发,可以理解成页面一开始是空白的元素,后面添加了新的元素使页面布局发生改变。

当渲染树的一部分因为元素的规模尺寸、布局、隐藏等改变需要重新构建的操作,会影响布局的操作。

重绘 :当计算好盒模型的位置、大小及其他属性后,浏览器根据每个盒子特性进行绘制。

当渲染树的一些元素只需更新属性,而这些属性只会影响元素的外观,而不影响布局的操作。浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式,这里就仅仅触发了重绘。

回流 触发时机

任何会改变元素几何信息(元素的位置和尺寸大小)的操作,都会触发回流。

1)添加或者删除可见的 DOM 元素;

2)元素的位置发生变化,元素尺寸改变(边距、填充、边框、宽度和高度);

3)内容变化。比如文本变化(用户在 input 框中输入文字)、图片被另一个不同尺寸的图片所替代;

4)浏览器窗口尺寸改变。如resize事件发生时。

5)获取一些特定属性的值。offsetTop、offsetLeft、

offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeigh。这些属性有一个共性,就是需要通过即时计算得到。因此浏览器为了获取这些值,也会进行回流。

6)当你修改网页的默认字体时。

常见的回流:

重绘 触发时机

回流必定会发生重绘,重绘不一定会引发回流。

常见的重绘:

1)使用 transform 替代 top

2)不要把节点的属性值放在一个循环里当成循环里的变量。

3)避免使用 table 布局,可能table 中每个元素的大小以及内容的改动会造成整个 table 的重新布局。

4)对于那些复杂的动画,对其设置 position: fixed/absolute,尽可能地使元素脱离文档流,从而减少对其他元素的影响

5)把 DOM 离线后修改。如:使用 documentFragment 对象在内存里操作 DOM。我们还可以通过通过设置元素属性display: none,将其从页面上去掉,然后再进行后续操作,这些后续操作也不会触发回流与重绘,这个过程称为离线操作。

6)如果想设定元素的样式,通过改变元素的 class 类名。不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 css 的 class,然后修改 DOM 的 className。

--end--

HTML 、 CSS 、 JavaScript 数据,经过浏览器中间渲染模块的处理,再加上 重排 、 重绘 、 合成 的一个个环节,才最终输出为屏幕上的 像素 视图画面。本文就逐一介绍 重排 、 重绘 、 合成 的基本概念、触发时机、影响范围以及其优化策略。

一个完整的渲染流程一般都经历如下过程:

定义: 当通过JS或css改变了元素的宽度、高度等,修改了元素的几何位置属性,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫 重排 。无疑, 重排需要更新完整的渲染流水线,所以开销也是最大的。

触发时机和影响范围: DOM节点信息更改,触发重排时,这个DOM更改程度会决定周边DOM更改范围。

全局范围: 就是从根节点html开始对整个渲染树进行重新布局,例如当我们改变了窗口尺寸或方向或者是修改了根元素的尺寸或者字体大小等。

局部范围: 对渲染树的某部分或某一个渲染对象进行重新布局。

定义: 如果修改了元素的背景颜色,并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫 重绘 。 相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些。

触发时机和影响范围: 每一次的dom更改或者css几何属性更改,都会引起一次浏览器的重排/重绘过程,而如果是css的非几何属性更改,则只会引起重绘过程。

定义: 合成是一种将页面的各个部分分离成层(Layer Tree),分别将它们栅格化,然后在称为“合成线程”的中组合为页面的技术。

触发时机和影响范围: 在GUI渲染线程后执行,将GUI渲染线程生成的绘制列表转换为位图,然后发送绘制图块命令 DrawQuad 给浏览器进程,浏览器进程根据 DrawQuad 消息生成页面,将页面显示到显示器上

优点: 我们使用了 CSS 的 transform 来实现动画效果,避开了 重排 和 重绘 阶段,直接在非主线程上执行合成动画操作。这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。

重排 一定会引起 重绘 ,而 重绘 不一定会引起 重排 , 重绘 的开销较小, 重排 的代价较高。在日常开发过程中应该尽量减少 重排 和 重绘 操作。

欢迎访问: 天问博客