前端

前端性能优化之重绘与重排

2020-04-28  本文已影响0人  若年

重排与重绘

当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。完成重排后,要将重新构建的渲染树渲染到屏幕上,这个过程就是“重绘”。

简单的说,重排负责元素的几何属性更新,重绘负责元素的样式更新。而且,重排必然带来重绘,但是重绘未必带来重排。比如,改变某个元素的背景,这个就不涉及元素的几何属性,所以只发生重绘。

优化策略

1 .将多次改变样式属性的操作合并成一次操作。那就是以后尽量都是操作class,在vue里面最好不要使用:style属性。都是操作class就可以了。
2 .将多次重排的元素设为absolute或者fixed,这样元素就脱离了文档流,他的变化不会影响到其他元素,比如有动画效果的元素。
3 .在内存中多次操作节点,完成之后在添加到文档中去。例如要获取异步表格,渲染到页面里面,可以先取得数据后在内存中构建整个表格的html片段,在一次性的添加到文档中去,而不是循环添加每一行。
4 .由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行复杂操作时,可以先隐藏他,操作完成之后在显示,这样只会在影藏和显示的时候触发2次重排。
5 .在需要经常取的,引起浏览器重排的属性值时,要缓存到变量。
6 .图片载入的时候设置宽高。
7 .把dom离线之后修改

//1 .使用documentFragment对象在内存里操作DOM

//2 .先把dom给display,然后在自由修改,修改完成之后显示出来

//3 .clone一个dom节点到内存里面,然后想怎么改就怎么改,改完之后,和在线的那个交换一下
let fragment = document.createDocumentFragment();
appendNode(fragment, data);
ul.appendChild(fragment);

//4 .不要把dom节点的属性值放在一个循环里面当成循环里面的变量,这样会导致大量的读写这个节点的属性

//5 .不要使用表格布局,因为任何微小的改变都会造成reflow

//6.将原始元素拷贝到一个独立的节点中,操作这个节点,然后覆盖原始元素
let old = document.querySelector('#mylist');
let clone = old.cloneNode(true);
appendNode(clone, data);
old.parentNode.replaceChild(clone, old);

8 .repaint过程利用了对比渲染前后的矩形,找出差异并且重新局部绘制差异部分。如果绘制出现了破坏缓存的情况,也会出现全局repaint的情况。

9.缓存布局信息

看以下样例:
将元素div向右下方平移,每次移动1px,起始位置100px, 100px。性能糟糕的代码
div.style.left = 1 + div.offsetLeft + 'px';
div.style.top = 1 + div.offsetTop + 'px';
这样造成的问题就是,每次都会访问div的offsetLeft,造成浏览器强制刷新渲染队列以获取最新的offsetLeft值。更好的办法就是,将这个值保存下来,避免重复取值
current = div.offsetLeft;
div.style.left = 1 + ++current + 'px';
div.style.top = 1 + ++current + 'px';
上一篇下一篇

猜你喜欢

热点阅读