绑定JSON数据时HTML表格的渲染缓慢

时间:2018-12-17 14:04:43

标签: javascript html angularjs

此处在webapi中使用angularjs(1.3)。

我有一个用户可以在其中上传excel文件的UI。我的api读取excel文件,并将行数据以JSON形式返回给UI。

然后,UI读取JSON并将其绑定回UI表。

此UI表的行和列是动态生成的,并且不是固定的,因此我正在HTML中使用contenteditable,因为用户可以添加更多行。

我可以从JSON精细读取并填充保存这些json值的数组。问题在于渲染时,屏幕被冻结并且需要时间来渲染所有数据。 我目前绑定约800行,并且屏幕冻结,并且大约需要10-15秒或更长时间来填充UI表。我将拥有更多数据,因此正在寻找解决方案。

我尝试调试,可以看到从API取回数据并从API读取JSON没有问题。填充数组时也没有问题。 一旦阵列填充,多数民众赞成在问题来临时。 UI冻结,需要花费一些时间来呈现这些数据。

我不确定这里发生了什么或为什么要花这么长时间才能渲染。以下是一些相关示例代码:

//Read json from the API

$http.get('https://api.myjson.com/bins/d1ugw').success(function(data) {
if (data.length > 0) {   

  $scope.setJson = data;
  $scope.initializeTable(true);
  var columns = $scope.targetTable.columns;

  //These are the 3 columns of the Table but can vary dynamically(currently just hardcoding it)
  var refColName = "state, month , year";

  //Push the columns to the table array
  var colArray = refColName.split(',');
  for (var i = 0; i < colArray.length; i++) {
    $scope.targetTable.columns.push({
      id: columns.length,
      refColName: refColName.split(',')[i]
    });
  }

  //Read the values from the json
  var idValues = $scope.getTableValues($scope.setJson, 'id');
  var commentValues = $scope.getTableValues($scope.setJson, 'comment');
  var rowValues = $scope.getTableValues($scope.setJson, 'refcol');
  var setIdValues = $scope.getTableValues($scope.setJson, 'sid');

  //Push the data back to the table array.
  $scope.pushRowData($scope.targetTable, rowValues, commentValues, idValues, setIdValues);
  //Till the above steps everything happens quickly and I can see $scope.targetTable being populated with my json. 
  //But after the above step the screen just freezes and takes time to show the entire data on the UI table.
 }
  });

以下是该用户界面的相关代码:

<tbody>
    <tr ng-repeat="r in targetTable.rows">
      <td class="fixed-width">
        <span>
            <a class="btn-xs" ng-show="row == $index" ng-if="targetTable.rows.length > 1"><i class="fa fa-times-circle" aria-hidden="true"></i></a>
        </span>
        <span contenteditable="true" ng-model="r.tableId" ng-change="addNewRow(r.tableId, r)">{{r.tableId}}</span>
      </td>
      <td class="fixed-width" contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="r[column.id]" ng-change="rowDataChange(r[column.id])"></td>
      <td class="comment-fixed-width" contenteditable="true" ng-model="r.comment" ng-change="rowDataChange(r.comment)"></td>
      <td class="blank fixed-width" colspan="2" ng-model="r[column.id]"></td>
    </tr>
  </tbody>

我创建了下面的JSFiddle以显示我的示例和面临的问题。

http://jsfiddle.net/aman1981/u1vbeos5/312/

我还在jsfiddle中添加了注释,以显示什么方法可以做什么。

如果有人可以帮助我解决此问题,我们将不胜感激。

3 个答案:

答案 0 :(得分:1)

首先,我建议您尽可能将Angular版本升级到最高级的版本。 还要检查动画版本。 除了您想到使用高级表格组件(例如ag-grid吗?)之外, 我可以加载10000行而没有任何问题。 https://www.ag-grid.com/

答案 1 :(得分:1)

以下是一些性能统计信息:

具有可编辑的内容(约4000个摘要调用)= 1.800毫秒-> http://prntscr.com/lweugn

没有可编辑的内容(约4个摘要调用)= 1.300毫秒-> http://prntscr.com/lweusn

分页仅显示前50个结果= 0.200ms-> http://prntscr.com/lwev09

由于DOM明显改变,您失去了最大的性能。但是请记住,摘要循环的数量和持续时间是获得良好性能的关键。尤其是当您有大量观察者时。这是直接比较: http://prntscr.com/lwf1nn正如您所看到的,摘要循环正在消耗总体性能的30%,但这并不是帧丢失的原因。帧丢失主要是由DOM更改引起的。绘制这么大的桌子需要一些时间。

当您的REST调用完成后,表格开始呈现。在我看来,此通话大约需要1.700毫秒。因此从开始到呈现结果大约需要3.500毫秒。即使分页为1.900ms。

我建议对搜索进行分页,但是无论如何您都可以尝试提高性能。

有用的链接是:

https://stackoverflow.com/a/47347260/8196542

https://www.codeproject.com/Articles/1173869/%2FArticles%2F1173869%2Fng-repeat-performance-degradation-at-case-of-very

答案 2 :(得分:0)

您的代码不断触发$ digest循环。 “监视”方法计算$ digest循环实际被调用的频率:

var nbDigest = 0;

$scope.$watch(function() {
  nbDigest++;
  console.log(nbDigest);
});

我敢打赌,这是造成您性能问题的原因。