分時函數(shù)優(yōu)化大數(shù)據(jù)量渲染


在我們的業(yè)務(wù)中,我們常常會?遇到大數(shù)據(jù)渲染,很早之前我們考慮到有用到虛擬列表,IntersectionObserver交叉觀察器,前端分頁查詢來優(yōu)化大數(shù)據(jù)量渲染


最近在讀《javascripts設(shè)計模式與開發(fā)實(shí)踐》發(fā)現(xiàn)有了另外一種方案分時函數(shù)

正文開始...

假設(shè)現(xiàn)在后端給了1000條數(shù)據(jù),現(xiàn)在前端需要展示

這不簡單嗎,不考慮性能情況下,直接循環(huán)創(chuàng)建dom渲染不就可以了嗎?

于是你寫了demo測試一下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>大數(shù)據(jù)</title>
    <style>
      * {
        padding: 0px;
        margin: 0px;
      }
    </style>
  </head>
  <body>
    <div id="app"></div>
  </body>
  </html>
引入js

  // arr后端mock數(shù)據(jù)
  var arr = [];
  var max = 1000;
  for (let i = 0; i < max; i++) {
    arr.push(i);
  }
  function renderList(sourceData) {
    const domApp = document.getElementById('app');
    const len = sourceData.length;
    for (let i = 0; i < len; i++) {
      const divDom = document.createElement('div');
      divDom.innerHTML = sourceData[i];
      domApp.appendChild(divDom);
    }
  }
  console.time('start');
  renderList(arr);
  console.timeEnd('start');
在控制臺打印發(fā)現(xiàn)執(zhí)行時間start: 5.104248046875 ms

以上是比較粗暴的方式,拿到后端數(shù)據(jù)直接在前端循環(huán)數(shù)據(jù),然后渲染,但是這種性能非常的低。



分時函數(shù)
參考《javascript設(shè)計模式與開發(fā)實(shí)踐》,分時函數(shù)主要思想是利用定時器,在一次性渲染1000條數(shù)據(jù),我把這1000條數(shù)據(jù)分割成若干份,在指定時間內(nèi)分片渲染完

具體參考下以下代碼

 var arr = [];
 var max = 1000;
 for (let i = 0; i < max; i++) {
    arr.push(i);
 }
// 創(chuàng)建一個分時函數(shù)
const timerChunk = (sourceArr, callback, count = 1, wait = 200) => {
  let ret, timer = null;
  const renderData = () => {
    for (let i=0;i<Math.min(count, sourceArr.length);i++) {
      // 取出數(shù)據(jù)
      ret = sourceArr.shift();
      callback(ret)
    }
  return function() {
    if (!timer) {
      timer = setInterval(() => {
        // 如果數(shù)據(jù)取完了,清空定時器
        if (sourceArr.length === 0) {
          clearInterval(timer);
          return;
        }
        renderData();
      }, wait)
    }
  }  
  }
}
const createElem = (res) => {
      const appDom = document.getElementById('app');
      const divDom = document.createElement('div');
      divDom.innerHTML = res;
      appDom.appendChild(divDom);
  };
var curentRender = timerChunk(arr, (res) => {
    createElem(res);
    // 每次取10條數(shù)據(jù),200ms
}, 10, 200);
 console.time('start');
 curentRender(); // start: 0.0341796875 ms
 console.timeEnd('start');
我們通過分時函數(shù)處理后,時間大概就是start: 0.037841796875 ms



對比以上兩種,使用分時函數(shù)后,速度提高了近120倍,因此使用分時函數(shù)優(yōu)化大數(shù)據(jù)量渲染是很有必要的。

總結(jié)
1、大數(shù)據(jù)量渲染暴力循環(huán)直接渲染性能差 2、分時函數(shù)處理大數(shù)據(jù)量渲染頁面性能高 3、本文示例code[1]

參考資料
[1]
code:
https://github.com/maicFir/lessonNote/tree/master/javascript/12-大數(shù)據(jù)






作者:Maic

歡迎關(guān)注微信公眾號 :web技術(shù)學(xué)苑