前端BootstrapTable元件不同使用方法的效率各有差異

資訊科技的風采發表於2021-07-07

本人需要解決的問題(#需求)

裝置端批量傳送資料過來,資料已按照特定欄位進行排序,現在本人需要按照傳過來的資料動態更新表格,表格的顯示區域有限制
因為一些原因,最終確定使用 Bootstrap Table 元件實現該功能

遇到的問題(#問題)

使用 bootstrapTable('load', {data: data})進行資料更新時,無法使用滾動條。每次重新整理滾動條都會恢復到滾動條頂部(即無法滑動滾動條,體驗很差)
使用 bootstrapTable('updateRow', {index : updateIndex, row : showRow}) 動態維護資料時,佔用CPU太多(30%+),導致 瀏覽器的IndexedDB資料庫無法使用等問題
使用 bootstrapTable('updateByUniqueId', {id: id, row : showRow}) 動態維護資料時,佔用CPU太多(30%+),導致 瀏覽器的IndexedDB資料庫無法使用等問題

測試前端頁面(#基本頁面)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <!-- Jquery 引用 -->
        <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>

        <!-- bootstrap && bootstrap-table -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" rel="stylesheet">
        <link href="https://unpkg.com/bootstrap-table@1.18.3/dist/bootstrap-table.min.css" rel="stylesheet">
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js"></script>
        <script src="https://unpkg.com/bootstrap-table@1.18.3/dist/bootstrap-table.min.js"></script>
        
    </head>
    <body>
        <div id="table-wrapper">
        <table id="table"
            data-toggle="table"
            data-show-columns="true"
            data-height="300"
            data-unique-id="uid"
        >
            <thead>
                <tr>
                      <th data-field="id">ID</th>
                      <th data-field="name">Item Name</th>
                      <th data-field="price">Item Price</th>
                </tr>
            </thead>
        </table>
        </div>
        <script>
      //  解決思路程式碼放在該處

          var $table = $('#table');
          var times = 0;
          var total = 0;
          var maxTotal = 0;


          function refresh(){
              //  問題程式碼
          }
          $(function() {
              setInterval(() =>{refresh();}, 2000);
          });

        </script>
    </body>
</html>

本人使用的基本思路

測試時的資料物件基本物件結構為 { 'id' : id, 'uid' : uid, 'name' : name, 'price' : price}

生成空物件的方法如下

function generateRow()
{
    var result = {
        'id' : 0
        , 'uid' : 0
        , 'name' : ''
        , 'price' : ''
      };
    return result;
}

Mock資料生成方法如下

function generateData()
{
    var data = [];
    let len = 20 + Math.floor(Math.random() * 30);
    for(let i = 0; i<len; i++)
    {
        let id = total + i + 1;
        data.push({
            'id' : id
            , 'uid' : (i+1)
            , 'name' : 'Item' + id
            , 'price' : '$' + id
        });
    }
    return data;
}
  • 問題一 實現程式碼

function refresh()
{
    var data = generateData();
    total += data.length;
    //  動態更新資料
    $table.bootstrapTable('load', data);
}

問題錄屏

無法正確使用滾動條

無法正確使用滾動條

記憶體佔用率

記憶體佔用率
  • 問題二 實現程式碼

function refresh()
{
    var data = generateData();
    var len = data.length;
    total += len;
    let updateIndex = 0;
    //  動態更新資料
    for(; updateIndex<maxTotal; updateIndex++)
    {
        let showRow = updateIndex<len ? data[updateIndex] : generateRow();
        $table.bootstrapTable('updateRow', {
            index : updateIndex
            , row : showRow
        });
    }
    //  插入資料
    for(;updateIndex<len; updateIndex++)
    {
        $table.bootstrapTable('insertRow', 
        {
            index : updateIndex
            , row : data[updateIndex]
        });
    }
    maxTotal = maxTotal >= len ? maxTotal : len;
}

問題截圖
CPU佔用過高

CPU佔用過高
  • 問題三 實現程式碼

function refresh()
{
    var data = generateData();
    var len = data.length;
    total += len;
    let updateIndex = 0;
    //  動態更新資料
    for(; updateIndex<maxTotal; updateIndex++)
    {
        let showRow = updateIndex<len ? data[updateIndex] : generateRow(updateIndex);
        $table.bootstrapTable('updateByUniqueId', {
            id : updateIndex
            , row : showRow
        });
    }
    //  插入資料
    for(;updateIndex<len; updateIndex++)
    {
        $table.bootstrapTable('insertRow', 
        {
            index : updateIndex
            , row : data[updateIndex]
        });
    }
    maxTotal = maxTotal >= len ? maxTotal : len;
}

問題截圖
CPU佔用過高

CPU佔用過高

最後的解決方法

在問題一的基礎上,外面巢狀 一層div,在這層 div中增加css屬性固定該div的高度,不用 bootstrapTable 的 data-height進行高度固定。

#table-wrapper {
    height : 400px;
    overflow : scroll;
} 

建議

問題結論,使用 load 直接重新整理載入 資料不會費太多CPU資源;使用動態 update 表格 重新整理資料會導致CPU佔用過高。建議使用 bootstrapTable直接 load 資料重新整理介面。

能夠使用CSS解決的問題,儘量別用JS。過程中走了彎路,經驗教訓

測試檔案

檔案下載地址: 在此下載

相關文章