浏览器的回流和重绘
浏览器的主要功能就是向服务端发送请求,下载解析资源显示在浏览器上
它的渲染机制是:
- 接收到HTML和CSS后,HTML经过解析渲染成DOM树,CSS经过解析生成CSSOM树,
- 将DOM树和CSSOM树两者结合,生成渲染树(Render Tree);Render Tree类似于DOM Tree但是又有很大的区别:Render Tree能识别样式,每个节点都有自己的样式,如果元素的display属性被设置成none,或者某个元素继承了这个属性都是不会被呈现出来的(会脱离文档流,不占据页面空间),但是visibility:hidden的元素会呈现出来(只是隐藏内容,并没有脱离文档流,会占据页面的空间),
- Layout(回流)根据生成的Render Tree,进行布局( Layout ),这样就知道所有节点的样式,然后计算它们在页面上的位置大小,
- Painting (重绘)根据渲染树及回流得到的几何信息,然后绘制页面,渲染到屏幕上
回流:
接收到HTML和CSS解析并添加到渲染树时,只是将 DOM 节点和它对应的样式结合起来,并不包含位置和大小信息。所以还需要 layout
这一过程计算他们的位置和大小,这一过程称为回流。 触发回流的行为有:元素的尺寸,布局,隐藏等改变而需要重新构建
重绘:
完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程就是重绘;触发重绘的行为有:改变页面的元素外观,风格,(color,background-color等)不会影响布局
总结: 回流一定会引起重绘,但是重绘不一定会引起回流,回流的性能消耗要比重绘大
会导致回流的操作:
页面的首次渲染,浏览器的窗口大小(如resize事件),尺寸(大小、外边距、边框),位置,内容(如字体变多变少,大小等)发生变化,添加或者删除操作等
使用下面等属性和方法 都需要返回最新的布局信息,它们也会触发回流重绘所以在修改样式的时候最好用一个变量存储起来避免多次获取刷新渲染队列
offsetTop、offsetLeft、offsetWidth、offsetHeight
scrollTop、scrollLeft、scrollWidth、scrollHeight
clientTop、clientLeft、clientWidth、clientHeight
getComputedStyle()
getBoundingClientRect
CSS优化:
1、 使用 visibility (只会引起重绘)替换 display: none(引发回流)
2、 避免使用table布局
3、将多次需要重绘的元素,position属性设置为absolute或fixed,元素脱离了文档流,它的变化不会影响到其他的元素
4、避免设置多层内联样式(通过style属性设置样式,每个dom元素都会造成回流)
5、避免使用 CSS 表达式(如:calc)
JS优化:
1、避免频繁操作DOM(当DOM发生改变时浏览器需要重新计算元素的几何属性,其他的元素也会收到影响,然后把计算的结果绘制出来)
2、避免频繁操作样式
3、也可以先为元素设置display: none
,然后进行页面布局操作结束后再把它显示出来