前端性能優(yōu)化-處理大批量DOM元素

一次性在dom添加多個(gè)節(jié)點(diǎn)會(huì)產(chǎn)生很大的性能問(wèn)題, 一次性加載多個(gè)dom元素的時(shí)候 頁(yè)面會(huì)出現(xiàn)首次加載緩慢或者瀏覽器直接崩潰掉,介紹兩種方法去優(yōu)化

1、分時(shí)函數(shù)

<script type="text/javascript">

    function createDom(data) {
      const div = document.createElement('div');
      div.innerHTML = data;
      document.body.appendChild(div);
    }  

    function chunkData (data, num, callback) {
    
    let time; 
    const start = function() { 
      for (let i = 0; i < Math.min(num, data.length); i++) {
        callback(data.shift());
      }
    }
    
   
      time = setInterval(function () {
        if(data.length === 0) {
          
          clearInterval(time);
        }
        start();
      } , 300);
    
    
  }
    window.onload = function () {
      const data = [];//要加載的數(shù)據(jù)
      for(var i = 0; i <= 10000; i++) {
        data.push(i);
      }
     for(let i = 0; i < data.length; i++) { //1.簡(jiǎn)單粗暴的方法
        createDom(i);
      }
    // chunkData(data, 20, createDom);//2.分時(shí)加載
    }
  
    </script> 

下圖一次性加載多個(gè)dom導(dǎo)致頁(yè)面加載時(shí)間變長(zhǎng)


一次性插入多個(gè)dom頁(yè)面渲染卡頓

采用分時(shí)加載后(使用chunkData方法)

分時(shí)加載

判斷渲染速度是否加快可以判斷當(dāng)發(fā)生 DOMContentLoaded 事件后,就會(huì)生成渲染樹(shù),生成渲染樹(shù)就可以進(jìn)行渲染了,這一過(guò)程更大程度上和硬件有關(guān)系了。

2、虛擬列表

虛擬列表的實(shí)現(xiàn)原理就是只渲染固定屏幕高度的幾條數(shù)據(jù) 每次改變dom元素內(nèi)容 模擬滾動(dòng) 盡量不要去用插入dom并且刪除dom這樣的方式去優(yōu)化 插入刪除dom會(huì)造成瀏覽器的開(kāi)銷 引起瀏覽器回流

  • visibleCount 為計(jì)算可視區(qū)域的渲染條數(shù)
  • listHeight 為列表的總高度 用于撐開(kāi)整個(gè)可視區(qū)域 用于滑動(dòng)
  • startIndexendIndex 用于截取渲染數(shù)據(jù)
componentDidMount() {
      const { data } = this.state; // 獲取的全部數(shù)據(jù)
      this.startIndex = 0 
      this.listHeight = data.length * this.itemSize;
      this.visibleCount = Math.ceil(500 / this.itemSize) // 500是可視區(qū)的高度  
      this.endIndex = this.visibleCount   

      this.setState({ visibleData: data.slice(0,this.visibleCount) });
      
    }

滾動(dòng)監(jiān)聽(tīng)事件

this.startOffset 的作用是用于定位可視區(qū)域的數(shù)據(jù),因?yàn)榛瑒?dòng)會(huì)將可視區(qū)域的列表向上滑動(dòng) 所以我們要計(jì)算整塊的高度 例如第2個(gè)元素要替換第1個(gè)元素的時(shí)刻 我們將列表向下定位一個(gè)塊的高度 這時(shí)候第一個(gè)元素就正好顯示在屏幕的第一個(gè)位置 否則第一個(gè)元素就會(huì)滑上去了 scrolltop減去this.scrollTop % this.itemSize是因?yàn)槲覀円圃旎瑒?dòng)效果 不能在第一個(gè)元素滑上去的距離小于一整塊高度的時(shí)候去調(diào)整他的top 這樣就不會(huì)有滑動(dòng)效果了


.wrapper {
  margin-top: 100px;
  border: 1px solid red;
 height: 500px;
  overflow: scroll;
  position: relative;
  -webkit-overflow-scrolling: touch;
}
.item {
  height: 50px;
  border: 1px solid darkcyan;

}

.phantom {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  z-index: -1;
}

.list {
  left: 0;
  right: 0;
  top: 0;
  position: absolute;
  text-align: center;
}

onScrollList = (val) => {
      const { data } = this.state;

      this.startIndex =  Math.floor(this.refs.lala.scrollTop / this.itemSize);
      this.endIndex = this.startIndex + this.visibleCount;
      this.scrollTop = this.refs.lala.scrollTop;
      this.startOffset = this.scrollTop - (this.scrollTop % this.itemSize);
      this.setState({ visibleData: data.slice(this.startIndex, Math.min(this.endIndex, data.length)) });
      
    }

render () {
      const { visibleData } = this.state;
      
      return (
        <div className='wrapper' ref={'lala'} onScroll={this.onScrollList}>
            <div className='phantom' style={{ height: this.listHeight + 'px' }}></div>
            <div className='list' style={{ top: this.startOffset + 'px' }}>
            {
              visibleData.map((item) => <div className='item'>{item}</div>)
            }
            </div>
            
        </div>
      )
    }
優(yōu)化前頁(yè)面卡住空白
渲染后性能綠油油????
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ??DOM(文檔對(duì)象模型)是針對(duì) HTML 和 XML 文檔的一個(gè) API(應(yīng)用程序編程接口)。 ??DOM 描繪...
    霜天曉閱讀 3,866評(píng)論 0 7
  • ??DOM 1 級(jí)主要定義的是 HTML 和 XML 文檔的底層結(jié)構(gòu)。 ??DOM2 和 DOM3 級(jí)則在這個(gè)結(jié)構(gòu)...
    霜天曉閱讀 1,599評(píng)論 1 3
  • 前端性能優(yōu)化資料整理 頁(yè)面性能差的直接后果是用戶需要等待,而等待,尤其是不確定要多長(zhǎng)時(shí)間的等待會(huì)給用戶帶來(lái)焦慮,為...
    飄零之雪閱讀 892評(píng)論 2 3
  • 關(guān)于前端性能優(yōu)化問(wèn)題詳解 出處:http://segmentfault.com/blogs 前端性能優(yōu)化指南 AJ...
    bennnnn閱讀 1,720評(píng)論 2 4
  • ??JavaScript 與 HTML 之間的交互是通過(guò)事件實(shí)現(xiàn)的。 ??事件,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,696評(píng)論 1 11

友情鏈接更多精彩內(nèi)容