绑定JSON数据时HTML表呈现缓慢



在此处使用angularjs(1.3(和webapi。

我有用户界面,用户可以上传excel文件。我的api读取excel文件,并以JSON形式将行数据返回到UI。

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

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

我可以从JSON fine中读取并填充包含这些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.
}
});

以下是UI的相关代码:

<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中添加了注释,以显示什么方法做什么。

如果有人能帮我解决这个问题,我将不胜感激。

以下是一些性能统计数据:

内容可编辑(约4000个摘要调用(=1.800ms->http://prntscr.com/lweugn

无内容可编辑(~4个摘要调用(=1.300ms->http://prntscr.com/lweusn

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

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

此外,当REST调用完成时,表开始呈现。在我的情况下,这个调用大约需要额外的1.700ms。因此,从开始到呈现结果需要将近3.500ms。即使分页1.900ms.

我建议使用带有搜索的分页,但无论如何都可以尝试提高性能。

有用的链接是:

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

https://www.codeproject.com/Articles/1173869/%2FArticles%2F1173869%2Fng-在非常的情况下重复性能下降

首先,如果可能的话,我建议您将Angular版本升级到最高级的版本。同时检查动画版本。除此之外,您还考虑使用高级表格组件,如ag grid?,我可以加载10000行而不会有任何问题。https://www.ag-grid.com/

您的代码正在反复触发$digest循环。"watch"方法计算$digest循环实际调用的频率:

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

我敢打赌这就是你的性能问题的原因。

最新更新