1、重排(回流):回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流。比如以下情况:
2、重绘
·DOM元素的字体颜色、改变visibility、outline、背景色。重绘不会带来DOM元素的重新计算,所以重绘并不一定伴随重排(回流),但是重排一定会引起浏览器的重绘
重绘,重排太过频繁,就会影响网页的执行性能。亲,你想想:你的页面本来一次可以重排好,你得多重排一次,那肯定是影响性能的。重绘一次就可以,你非得多重绘继承,那肯定也是影响性能的。
跟生活中一样。
重绘:你不停地擦掉重画,擦掉重画,肯定不如一次画到位好
重排:你总是重复性的把某个物体不停地挪动。跟家里的家具要换位置的道理一样。你如果想不来,今晚回去思考一下:假定你要把家里的家具重新布局(从A布局变成B布局),你在家具搬动的过程中,可以出几套搬动方案。看看哪一种搬动方案是挪动家具次数最少的,那么这种方案就是重排的最优方案。
浏览器也是很聪明的,由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。但是!当你获取布局信息的操作的时候,会强制队列刷新,比如当你访问以下属性或者使用以下方法:
offsetTop、offsetLeft、offsetWidth、offsetHeight
scrollTop、scrollLeft、scrollWidth、scrollHeight
clientTop、clientLeft、clientWidth、clientHeight
getComputedStyle()
getBoundingClientRect()
以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。这也是为什么在获取这些值时会引起重排(回流)、重绘的原因,因此,我们在修改样式的时候,最好避免使用上面列出的属性,他们都会刷新渲染队列。如果要使用它们,最好将值先保存起来。
1、分离读和写的操作(避免触发同步布局事件):
let ulDom = document.getElementById(“box”);
var curLeft=ulDom .offsetLeft;
var curTop=ulDom .offsetTop;
ulDom .style.left=curLeft+1+'px';
ulDom .style.top=curTop+1+'px';
而不要这样写:
let ulDom = document.getElementById(“box”);
var curLeft=ulDom .offsetLeft;
ulDom .style.left=curLeft+1+'px';
var curTop=ulDom .offsetTop;
ulDom .style.top=curTop+1+'px';
因为,获取offsetLeft和offsetTop会导致浏览器强制清空队列,进行强制同步布局。
2、样式集中改变,而不要一个一个的改变(减少重绘重排)
如:let ulDom = document.getElementById(“box”);
ulDom.style.left = “100px”;
ulDom.style.top = “200px”;
最好改成如下(cssText):
let ulDom = document.getElementById(“box”);
ulDom.style.cssText = ‘left :100px;top:200px;’
或者使用class名也可以
ulDom.className = “boxcls”;
3、批量修改DOM
1)、如果可以的话,在重排时,可以使用absolute脱离文档流,这样,元素的尺寸改变时,就不会影响其它元素了。先让元素absolute。然后给元素中放入若干个dom,再把元素的absolute去掉;
如果可以的话,使用display:none(脱离文档流),等元素的样式属性改变完毕后,再让元素显示。
2)、使用createDocumentFragment或拼接html字符串的方式进行DOM的增加。