Js實現渲染上萬條數據頁面不卡住


setTimeout(() => {
  // 插入十萬條數據
  const total = 100000;
  // 一次插入的數據
  const once = 20;
  // 插入數據需要的次數
  const loopCount = Math.ceil(total / once);
  let countOfRender = 0;
  const ul = document.querySelector('ul');
  // 添加數據的方法
  function add() {
    const fragment = document.createDocumentFragment();
    for(let i = 0; i < once; i++) {
      const li = document.createElement('li');
      li.innerText = Math.floor(Math.random() * total);
      fragment.appendChild(li);
    }
    ul.appendChild(fragment);
    countOfRender += 1;
    loop();
  }
  function loop() {
    if(countOfRender < loopCount) {
      window.requestAnimationFrame(add);
    }
  }
  loop();
}, 0)

原理:渲染大數據時,合理使用createDocumentFragment和requestAnimationFrame,將操作切分為一小段一小段執行。

documentFragment:

    是一個虛擬的Dom列表,可以儲存待處理的xml片段(el元素),因為他不在真實的Dom結構中,所以對它所做的操作不會觸發瀏覽器的回流,只會在他插入dom的時候觸發一次而已。

    上面把多個動態生成的div插入到了虛擬節點里,在最后完成之后只做了一次插入,這樣就只會觸發一次回流。
    但是在數量太多的時候,哪怕是一次插入,也會因為瀏覽器渲染不過來導致失去響應,這時候就需要增加一定的時間間隔,可以使用setTimeout,也可以使用一個api------requestAnimationFrame

requestAnimationFrame()

    1.方法是為了動畫 專門使用的api,在通常的動畫中會定義一個定時器來幾秒幾秒的發生變化,但是為了性能和更加方便,它提供了這個可以在1秒鍾運行大約60次(≈16.7ms)回調的api。
    而且會把這一刻所有的dom操作緩存起來,在一次回流重繪中完成操作,它的每次調用並不是指定時間的,而是跟緊瀏覽器的刷新頻率,所以可以做到:在瀏覽器的刷新頻率時進行回流,保證性能效率。
    當頁面不是激活狀態的情況下,這個函數將會停止回調,進行暫停來節省cpu操作。激活時再繼續。
    在元素隱藏時不會進行重繪回流。

    2.它的返回值為一個long的標識符,和settimeout一樣,可以調用cancelAnimationFrame()傳入這個標識符來取消這個回調。
    使用這個可以在瀏覽器下一次’刷新’的時候運行指定的回調,在這里來插入這多個節點。
    使用這樣可以大批量插入很多數據 頁面也不會失去響應卡住,可以保證比較好的性能


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM