参考文章:
http://t.csdnimg.cn/Ko4qg
https://baijiahao.baidu.com/s?id=1732514823204412529&wfr=spider&for=pc
一、页面渲染流程
- 解析html绘制DOM树
- 解析css绘制CSS树
- 把DOM和CSSOM组合生成render tree(渲染树)
- 在渲染树的基础上进行布局,计算每个节点的几何结构
- 把每个节点绘制到屏幕上(painting)
二、什么是重排和重绘
重排:也叫回流Layout
也就是重新布局。当DOM 结构发生变化,或者页面中的元素位置、尺寸等属性发生变化时,浏览器需要重新计算元素的几何属性,然后再次布局页面。
重排会影响到整个页面的布局,因此是比较昂贵的操作,会导致页面性能下降。
重绘:
也就是重新排列。
是在一个元素的外观被改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
重绘不一定重排,但重排一定重绘
三、怎么触发
重排
- 增加或删除元素
- 元素尺寸变化(外边距、内边距、边框厚度、宽高等几何属性)
- 元素位置改变,或者使用动画
- 浏览器窗口尺寸改变(resize事件发生时)
- 计算某些属性:如调用offsetTop、offsetLeft、scrollTop、scrollLeft、clientTop、clientLeft、getBoundingClientRect或scrollIntoView等属性和方法。
重绘
- 外观属性
背景、透明度、 - 文字
text、font
参考文章:http://t.csdnimg.cn/Qrbgv
四、特点
- 重排是一种比较昂贵的操作,因为它会导致浏览器重新计算并更新 DOM 树。
- 重绘的成本通常比重排低,因为它不需要重新计算布局。
五、如何减少不必要的重排和重绘
css的角度
- 减少直接操作dom元素,不要一条一条地修改 DOM 的样式,改用className用于控制
- 尽可能在DOM树的最末端改变class;
- 动画尽量用css,少用js (比如transform和opacity
- 避免使用table布局:可能很小的一个小改动会造成整个table的重新布局(可以设置table-layout:auto,或者table-layout:fixed,这样可以让table一行一行的渲染,这种做法是为了限制reflow的影响范围。)
- 使用absolute或fixed脱离文档流
使用绝对定会使的该元素单独成为渲染树中的body的一个子元素,重排开销比较小,不会对其它节点造成太多的影响,当你在这些节点上放置这个元素时,一些其它在这个区域内的节点可能需要重绘,但是不需要重排。
JS操作的角度
- 批量修改DOM:
- 通过documentFragment创建一个dom碎片,在它上面操作完成之后,在添加到文档中,这样就只触发一次重排
- 先隐藏元素,进行修改后再显示该元素,因为display:none上的DOM操作不会引发回流和重绘,因为已经不在渲染树中了
- 不要把DOM节点的属性值(例如offestTop)放在循环里当成变量