美文网首页前端
前端性能优化之重绘与重排

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

作者: 若年 | 来源:发表于2020-04-28 11:34 被阅读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';
    

    相关文章

      网友评论

        本文标题:前端性能优化之重绘与重排

        本文链接:https://www.haomeiwen.com/subject/xqhvwhtx.html