渲染树的构建
在dom树和cssdom树都渲染完成之后,就会开始构建渲染树。渲染树就是对dom和cssdom树的结合,得到每一个节点对应什么样式的数据结构。这个结合的过程大体上是遍历整个dom树。然后再cssdom树里匹配到对应的样式。渲染树有一下几个特点:
1.渲染树的根节点是html
在 Google Web Fundamentals 这个文档中,渲染树的根节点是body,实际上html节点上的样式也是可以显示再页面上的,而head标签里的内容和显示没有关系,所以渲染树是没head这部分的。
2.渲染树和dom树的结构并不完全一致
渲染树会把所有不可见的元素忽略掉,所以dom树的节点有display:none;属性节点以及他的子节点,最终都不会出现在渲染树中。但是有visicility:hidden样式的元素会出现在渲染树中,因为具有这个样式的元素是需要占位的,只不过是它不显示出来。
3.样式优先级
同一个dom节点,会匹配多个cssdom节点,而最终显示的由哪个css样式来确定,就是样式优先级的问题了。当一个元素有多个样式的时候,样式优先级的顺序是:
内联样式 > ID选择器 > 类选择器 > 标签选择器 > 通用选择器 > 继承样式 > 浏览器默认样式
还有一套计算优先级的方法,浏览器对每个css样式都有一个权重值,需要确定优先级时,直接用公司计算整条选择器的权重作为该样式的优先级:
- 内联样式权重值 1000
- id权重值100
- 类选择器、属性选择器和伪类选择器里样式的权重是10
- 标签选择器里样式的权重是1
- 通用选择器直接忽略
布局(layout)
渲染完成后,计算渲染树上的每个节点后,技能计算出每个元素所占空间的大小和位置。这个过程就是布局。
绘制(paint)
布局之后,每个元素的大小位置就有了,经过最后绘制这一步,就可以把样式绘制在屏幕上,在绘制过程中,浏览器会调用图像处理器,逐层逐块的把所有计算好位置和样式的元素都绘制出来。 ###重排(reflow)和重绘(repaint) 渲染树是动态构建的,dom节点和css节点的改动,都可能造成渲染树的重建,渲染树的改动就会造成重排重绘,下面我们介绍这两个概念,以及他们在什么情况下出发:
1、重排
当我们在dom中新增和删除了元素,或者是改变了某些元素的大小和位置和布局,在这个时候渲染树里,这个有改动的节点和它影响到的节点,都要重新计算,在改变发生时,要重新经历dom的改动,cssdom的构建,渲染树的构建、布局和绘制整个流程,这个过程就叫做 "重排",也叫做 "回流"。
2、重绘
重绘是我们改变元素的字体颜色和背景色的时候,并不会改变它的大小和位置,也不会影响到其他元素的布局,浏览器会对直接对元素的样式重新绘制,这个过程就叫重绘。
知识拓展
如何减少重排重绘 可以通过这几种方式进行优化
- 不要逐项更改样式可以把需要的样式逐项手机起来,用一次操作进行修改
- 用class的变动替代直接样式修改
- 不要循环操作dom,循环的结果也要收集起来,最后用一次操作来完成
- 需要频繁改动的元素(比如动画)尽量使用绝对定位,脱离文档流的元素会减少对后面元素的影响
- 在条件允许的情况下,尽量使用css3动画,它可以调动gpu执行渲染