回流和重绘

重绘:元素的样式改变(但是宽高,大小,位置等不变)

比如:outline, bisibility,color,background-color等位置大小没有变但是样式变了,引发重绘

回流重排:理解为位置的重新排列):元素大小或者位置发生了改变(页面布局和几何信息发生了改变),触发了重新的布局,导致渲染重新计算布局和渲染。

比如:添加或者删除可见的DOM元素,元素的位置发生了变化,元素的尺寸发生变化,视口大小的变化;页面一开始渲染;

注意:回流一定会触发重绘,重绘不一定会触发回流

性能优化:

​ 尽可能的减少DOM的回流和重绘(重排)

  • 放弃传统的dom操作,基于vue/react开始数据影响视图

    mvvm/mvc/virtual dom/ dom diff.....最大限度的减少操作DOM

  • 分离读写操作(现代的浏览器有渲染队列机制)

    offsetTop, offsetLeft, offsetWidth, offsetHeight

    clientTop, clientLeft, clientWidth, clientHeight

    scrollLeft, scrollTop, scrollWidth scrollHeight

    getComputedStyle, currentStyle, 会刷新渲染队列

  • 样式集中改变(批量处理)

    box.style.cssText = 'width:200';
    box.className 
    box.classList.add();// 定义好的样式
    
  • 缓存布局信息

    let a = box.clientHeight;
    let b = box.clientWidth;
    // box.style.width = box.clientWidth + 10 +'px'
    // box.style.height = box.clientHeigth + 10 + 'px'
    box.style.width = a + 10 + 'px';
    box.style.height = b + 10 + 'px';
    
  • 元素的批量修改

    1. document.createDocumentFragment() 文档对象的容器

      <ul id="box">
      
      </ul>
      <script>
          let frag = document.createDocumentFragment();
          for (let i = 1; i <= 5; i++) {
              let newLi = document.createElement('li');
              newLi.innerText = i;
              frag.appendChild(newLi);
          }
          box.appendChild(frag);
        // 只触发一次回流
      </script>
      
    2. 模板字符串拼接

      <script>
        let str = ``;
        for (let i = 1; i <= 5; i++) {
          str += `<li> ${i}</li>`;
        }
        box.innerHTML = str;
      </script>
      
  • 动画效果应用到position属性为fixed或者absolute上(脱离文档流,对其他的元素影响较小)

  • CSS3中的硬件加速

    transform/opcacity/ filters ,这些回流不会引发回流和重绘

    缺点:占用大量的内存,使字体模糊

  • 牺牲平滑换速度

  • 避免使用table布局和使用css的JavaScript表达式

posted @ 2021-02-28 15:44  HelloCoderRookie  阅读(209)  评论(0编辑  收藏  举报