1、前言css
偶尔在面试过程当中遇到太重汇与回流reflow的问题,毕竟页面优化也是考核一个开发者能力的关键之一,上篇文章聊了下documentfragment也是为了减轻回流问题,那么本篇文章好好介绍下重绘和回流。html
2、重绘和回流是什么面试
怎么去理解这两个概念呢?从字面上理解,重绘,从新绘画,从新上色,较难产生联想的是回流。浏览器
咱们都知道,一个页面从加载到完成,首先是构建DOM树,而后根据DOM节点的几何属性造成render树(渲染树),当渲染树构建完成,页面就根据DOM树开始布局了,渲染树也根据设置的样式对应的渲染这些节点。缓存
在这个过程当中,回流与DOM树,渲染树有关,重绘与渲染树有关,怎么去理解呢?布局
好比咱们增删DOM节点,修改一个元素的宽高,页面布局发生变化,DOM树结构发生变化,那么确定要从新构建DOM树,而DOM树与渲染树是紧密相连的,DOM树构建完,渲染树也会随之对页面进行再次渲染,这个过程就叫回流。字体
当你给一个元素更换颜色,这样的行为是不会影响页面布局的,DOM树不会变化,但颜色变了,渲染树得从新渲染页面,这就是重汇。优化
你应该能感受到,回流的代价要远大于重绘。且回流必然会形成重绘,但重绘不必定会形成回流。动画
题外话spa
1.因为display为none的元素在页面不须要渲染,渲染树构建不会包括这些节点;但visibility为hidden的元素会在渲染树中。由于display为none会脱离文档流,visibility为hidden虽然看不到,但相似与透明度为0,其实还在文档流中,仍是有渲染的过程。
2.尽可能避免使用表格布局,当咱们不为表格td添加固定宽度时,一列的td的宽度会以最宽td的宽做为渲染标准,假设前几行td在渲染时都渲染好了,结果下面某行的一个td特别宽,table为了统一宽,前几行的td会回流从新计算宽度,这是个很耗时的事情。
3、重绘和回流有什么区别
结合上面的解释,引发DOM树结构变化,页面布局变化的行为叫回流,且回流必定伴随重绘。
只是样式的变化,不会引发DOM树变化,页面布局变化的行为叫重绘,且重绘不必定会便随回流。
它们的区别就像这样:
回流每每伴随着布局的变化,代价较大
重绘只是样式的变化,结构不会变化
4、怎么减小回流
说了这么多,咱们也知道了,回流要从新构建DOM树,渲染树也得从新渲染,很麻烦,哪么哪些行为会引发回流,怎么去避免呢?
1.DOM的增删行为
好比你要删除某个节点,给某个父元素增长子元素,这类操做都会引发回流。若是要加多个子元素,最好使用documentfragment。
2.几何属性的变化
好比元素宽高变了,border变了,字体大小变了,这种直接会引发页面布局变化的操做也会引发回流。若是你要改变多个属性,最好将这些属性定义在一个class中,直接修改class名,这样只用引发一次回流。
3.元素位置的变化
修改一个元素的左右margin,padding之类的操做,因此在作元素位移的动画,不要更改margin之类的属性,使用定位脱离文档流后改变位置会更好。
4.获取元素的偏移量属性
例如获取一个元素的scrollTop、scrollLeft、scrollWidth、offsetTop、offsetLeft、offsetWidth、offsetHeight之类的属性,浏览器为了保证值的正确也会回流取得最新的值,因此若是你要屡次操做,最取完作个缓存。
5.页面初次渲染
这样的回流没法避免
6.浏览器窗口尺寸改变
resize事件发生也会引发回流。
这里就不列举引发重绘的行为了,记住,回流必定伴随着重绘,因此上面的行为都会重绘,除此以外,例如修改背景颜色,字体颜色之类不影响布局的行为都只引起重绘。
若是对于documentfragment文档片断感兴趣,能够阅读博主这篇文章。
参考资料