一、浏览器渲染过程?
[原文](https://blog.csdn.net/qq_42269433/article/details/81133772)
1. 浏览器把获取到的html代码解析成1个Dom树,html中的每个tag都是Dom树中的1个
节点,根节点就是我们常用的document对象 。dom树里面包含了所有的html tag,
包括display:none隐藏,还有用JS动态添加的元素等。
浏览器把所有样式(主要包括css和浏览器的样式设置)解析成样式结构体,在解析的
过程中会去掉浏览器不能识别的样式,比如IE会去掉-moz开头的样式.
dom tree和样式结构体(cssom)结合后构建呈现树(render tree),render tree有点类似
于dom tree,但其实区别有很大,render tree能识别样式,render tree中每个node
都有自己的style,而且render tree不包含隐藏的节点(比如display:none的节点,还
有head节点),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含
到 render tree中。
注意: visibility:hidden隐藏的元素还是会包含到render tree中的,因visibility:hidden
会影响布局(layout),会占有空间。
1.1 dom树结构,cssom,renderTree
CSSOM : 样式表解析完毕后,系统会根据选择器将CSS规则添加到对应的哈希表中。这些哈希表包括:ID哈希表、类名称哈希表、标记名哈希表等,还有一种通用哈希表,适合不属于上述类别的规则。如果选择器是ID,规则就会添加到ID表中;如果选择器是类,规则就会添加到类表中。
注意:此处的cssom(样式结构体)尚有疑问。
1.2 cssom和dom树怎么匹配结合成renderTree ?
(以dom节点匹配cssom)
从本渲染结点开始,判断此结点是否与选择器链表的当前选择器相匹配。如果匹配,
判断此选择器与下一个选择器的关系:如果为NONE,表示本选择器是选择器链的最
后一个,返回成功;如果关系为AND (比如:#id.class),选择下一个选择器与本渲染
结点继续比较;如果关系为CHILD,表示本选择器是下一个选择器的子结点,返回下
一个选择器与下一个渲染结点的匹配结果;否则,关系为DESCENDANT,选择器和
渲染结点各指向下一个结点,然后将渲染结点继续回溯,直到第一个满足回溯后的选
择器的结点,此时将继续判断回溯后的选择器和回溯后的渲染结点是否匹配。
二、什么是重绘?回流(重排)?
-
当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流。每个页面至少需要一次回流,就是在页面第一次加载的时候。
-
当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
注:回流必将引起重绘,而重绘不一定会引起回流。
三、哪些情况会发生重绘,回流?
—不同的条件下发生重排的范围及程度会不同 :
1.页面初始渲染
2.改变字体,改变元素尺寸(宽、高、内外边距、边框,改变元素位置等
各种情况:
设置 style 属性的值
激活 CSS 伪类,比如 :hover
操作 class 属性
css3的某些属性(https://csstriggers.com/ 结合此链接查看哪些属性会触发重排
、哪些属性会触发重绘以及哪些属性会触发合成;)
(注意:如果修改属性不影响布局则不会发生重排)
3…改变元素内容(文本或图片等或比如用户在input框中输入文字)
4.添加/删除可见DOM元素(注意:如果是删除本身就display:none的元素不会发生重排;visibility:hidden的元素显示或隐藏不影响重排)
5.fixed定位的元素,在拖动滚动条的时候会一直回流
- 调整窗口大小(Resizing the window)
7.计算 offsetWidth 和 offsetHeight 属性【注释2】
【注释2:flush队列】
浏览器是聪明的,当对以下属性进行操作的时候:
包括:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。
浏览器不会马上操作它们,而是会先缓存在队列中,有一定时间顺序去执行这些操作,但是在这过程中我们需要去获取在该队列中的属性时,浏览器为取得正确的值就会触发重排。这样就使得浏览器的优化失效了。
所以,在多次使用这些值时应进行缓存。
四、如何减少回流,重绘?
4.1.修改html元素中对应的class名,利用class替换样式
【代码示例】