我遇到了运行Angular 1.5.9的旧应用程序的问题。控制器包含以下循环,该循环由" Select All"页面上的链接:
var len = $scope.payments.length, i;
for (i = 0; i < len; i++) {
$scope.payments[i].selected = true;
}
payment数组中对象中的selected属性绑定到视图中的复选框:
<tr data-ng-repeat="payment in payments | orderBy: 'payDate'">
<td><input type="checkbox" data-ng-model="payment.selected" data-ng-change="setSelectedTotal()"/>...
表中的数组/行中最多有15000个项目,并且在页面加载后第一次单击“全选”链接时,最多需要40秒才能刷新视图并选中所有复选框。如果我清除复选框,然后再次单击“全选”链接,则复选框将在大约1秒或更短的时间内显示为已选中。所有随后点击“全选”链接的情况都是如此 - 它只是第一次变慢,但每次只需要一秒或更短时间。我怀疑这与模型绑定有关,因为当我用console.time()和console.timeEnd()包围循环时,循环只需要几秒钟甚至第一次尝试。所以问题在于循环完成后发生的事情。我尝试过从ng-model切换到ng-checked只是为了看看它是否会加快速度,但它给了我一个错误,实际上应用程序依赖于绑定到所选属性的复选框。我还尝试在页面加载的第一千个复选框上运行select all(后面是全部清除),但这没有任何区别。任何洞察它为什么第一次如此缓慢和/或如何加快它将非常感激。
答案 0 :(得分:1)
以下是一些优化示例。
注意:我使用document.querySelectorAll在控制器之外选择/取消选择,因为它比依赖$ scope数据快得多。
angular.module('app', []);
angular.module('app')
.controller('ExampleController', ['$scope', function($scope) {
$scope.payments = [];
$scope.selected = false;
$scope.total = 0;
$scope.itemsCount = 7500;
// Populate with
populate($scope.itemsCount);
$scope.updateTotal = function() {
let total = 0;
for (let i = 0; i < $scope.payments.length; i++) {
if ($scope.payments[i].selected === true) {
total += $scope.payments[i].amount;
}
}
$scope.total = total;
}
$scope.toggleAll = function() {
// Toggle global selected state
$scope.selected = !$scope.selected;
for (let i = 0; i < $scope.payments.length; i++) {
$scope.payments[i].selected = $scope.selected;
}
$scope.updateTotal();
}
$scope.toggle = function(index) {
$scope.payments[index].selected = !$scope.payments[index].selected;
$scope.updateTotal();
}
function populate(count) {
for (let i = 0; i < count; i++) {
$scope.payments.push({
amount: i,
selected: false
});
}
}
}]);
// Toggle all checkbox
function vanillaToggleAll(event) {
var el = event.srcElement || event.target;
var checkboxes = document.querySelectorAll("input[type='checkbox']");
for (let i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = el.checked;
}
}
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="ExampleController">
<h1>Items: {{itemsCount}}, Total: {{total}} USD</h1>
<table>
<thead>
<tr>
<td>
<input type="checkbox" ng-click="toggleAll()" onclick="vanillaToggleAll(event)">
<label>Select/Unselect All</label>
</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="payment in payments | orderBy: 'amount'">
<td>
<input type="checkbox" class="checkbox" ng-bind="payment.selected" ng-click="toggle($index)" />
<label ng-bind="::payment.amount"></label> USD
</td>
</tr>
</tbody>
</table>
</body>
</html>
A demo plunker 7500 项目
以下是结果,我使用Chrome分析器来分析加载,编写脚本,渲染所花费的时间......
1000件
10000件
15000件