重排:当改变dom结构的时候,就会从dom树开始从新渲染页面,这过程叫重排比如添加或者删除可见的DOM元素、元素尺寸改变、元素内容改变、浏览器窗口尺寸改变等等
重绘:当改变样式(不改变几何结构)的时候,它会从render树开始重新开始渲染页面,这过程叫重绘,比如改变颜色,透明等
怎么减少重排与重绘?
一、减少重排的范围
①.尽可能的在DOM树的最末端改变class,重排是不可避免的,但是可以减少其影响,尽可能的在DOM树的最末端改变class,可以限制重排的范围,尽可能少的影响其他节点。
②.不要使用table布局,可能很小的一个小改动会造成整个table的重新布局,在不得已使用table的场合,可以设置table-layout:auto,或者table-layout:fixed,这样可以让table一行一行的渲染,这种做法是为了限制reflow的影响范围。
二、减少重排的次数
①.样式集中改变
不要频繁的操作样式,对于一个静态页面来说,明智且可维护的做法是更改类名,而不是修改样式。对于动态改变的样式来说,相较每次微小修改都直接触及元素,更好的办法是统一在cssText变量中编辑。虽然现在大部分现代浏览器会有flush队列进行渲染队列优化,但是有些老版本的浏览器效率依然低下。
②.分离读写操作
DOM的多个读操作或者写操作,应该放在一起,不要两个读操作之间加入一个写操作
当我们修改了元素的集合属性,导致浏览器触发重排或重绘时,它会把该操作放进渲染队列,等到队列中操作到了一定的数量或者到了一定的时间间隔时,浏览器就会批量执行这些操作。
③.将DOM离线
使用display:none; 一旦我们给元素设置display:none时(只有一次重排重绘),元素便不会再存在在渲染树种,相当于将其从页面上“拿调”,我们之后的操作将不会触发重绘和重排,添加足够多的变更后,通过display属性显示(另一次重排重绘)。通过这种方式即时大量变更也只是触发两次重排,visibility:hidden的元素只对重绘有影响,不影响重排
通过documentFragment创建一个dom碎片,在它上面批量操作dom,操作完成之后,再添加到文档中,这样只会触发一次重排。
复制节点,在副本上工作,然后替换他。
④.使用absolute或fixed脱离文档流
使用绝对定会使的该元素单独成为渲染树中的body的一个子元素,重排开销比较小,不会对其它节点造成太多的影响,当你在这些节点上放置这个元素时,,一些其它在这个区域内的节点可能需要重绘,但是不需要重排。
⑤.优化动画
可以把动画效果应用到position属性为absolute或fixed的元素上,这样对其他元素影响较小。
启用GPU加速GPU硬件加速是指应用GPU的图形性能对浏览器中的一些图形操作交给GPU来完成,GPU专门是为处理图形而设计的,在速度和能耗上更有效率。