重排(重构/回流/reflow) 重绘(repaint/redraw)
一、浏览器运行机制
浏览器加载完html后生成 DOM树 ,这是页面的结构,页面所有元素按这个结构排列;
在加载完css和js后生成 渲染树 ,页面中的元素都有自己的规模尺寸(宽高)、位置、颜色等,按渲染树将页面绘制在浏览器上。
重排
1、当页面中的某些元素的规模尺寸、布局发生改变或元素的隐藏等都会触发渲染树重新构建。
每个页面至少触发一次重排和重绘(浏览器第一次加载页面时,页面初始化)
2、触发重排的情况:
1⃣️页面的初始化(无法避免)
2⃣️页面增加、删除、隐藏元素
3⃣️改变元素的宽高、位置,使用动画
4⃣️浏览器窗口尺寸的改变(resize事件)
5⃣️读取某些元素属性:(offsetLeft/Top/Height/Width, clientTop/Left/Width/Height, scrollTop/Left/Width/Height, width/height, getComputedStyle(), currentStyle(IE) )
重绘
当页面中的元素的颜色或背景色发生改变时,就会触发重绘。
注意:table及其内部元素可能需要多次计算才能确定好其在渲染树中节点的属性值,比同等元素要多花两倍时间,这就是我们尽量避免使用table布局页面的原因之一。
重排一定触发重绘,重绘不一定触发重排。
重排重绘的代价:浏览器运行速度减慢、耗时,浏览器卡死
二、优化
1、浏览器自己的优化
浏览器回维护一个队列,将所有的重排重绘放在这个队列中,当达到一定的数量或一定的时间间隔后再触发一次重排重绘。(此期间不要访问DOM元素的offsetleft等属性)
2、我们的优化
1⃣️尽量批次改变元素css属性
2⃣️将动画的元素设置position属性为absolute或fixed,这样使元素脱离文本流,不会影响渲染树。
3⃣️当多个添加DOM元素时,使用文本碎片fragment(隐藏的元素不再渲染树中,)只触发一次重排重绘