此处在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中添加了注释,以显示什么方法可以做什么。
如果有人可以帮助我解决此问题,我们将不胜感激。
答案 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。
我建议对搜索进行分页,但是无论如何您都可以尝试提高性能。
有用的链接是:
答案 2 :(得分:0)
您的代码不断触发$ digest循环。 “监视”方法计算$ digest循环实际被调用的频率:
var nbDigest = 0;
$scope.$watch(function() {
nbDigest++;
console.log(nbDigest);
});
我敢打赌,这是造成您性能问题的原因。