我正在测试 AngularJS 的性能,以确定它是否适合我们的应用程序。为了衡量和比较 DOM 创建的速度,我创建了一个 JSFiddle example人们可以在这里玩弄不同数量的元素来创造。
目标是显示按项目排序的 n 个随机用户。有基于项目类型的内容,如果用户是 secret ,则根本不应该显示。
HTML:
<div ng-repeat="user in users | orderBy:'project'" post-repeat-directive
ng-if="user.secretagent == false"
class="user"
ng-class="{male: (user.gender == 'm'), female: (user.gender != 'm')}"
ng-switch="user.project">
<h2>{{user.name}}</h2>
Project: {{user.project}}
<em ng-switch-when="fame">[fame]</em>
<em ng-switch-when="idol">[idol]</em>
</div>
Javascript:
angular.module('AngularBench', [])
.config(['$compileProvider', function ($compileProvider) {
$compileProvider.debugInfoEnabled(false);
}])
.controller("benchmarkController", ['$scope', 'TimeTracker', function($scope, TimeTracker) {
$scope.result = undefined;
$scope.users = [];
$scope.benchmark = function(size) {
TimeTracker.clockStartDate(size);
var users = getUsers(size);
$scope.users = users;
$scope.$watch(
function () { return TimeTracker.getDuration(); },
function(newVal, oldVal) { $scope.result = newVal; },
true
);
};
}])
.factory('TimeTracker', function() {
var start, end, duration;
return {
clockStartDate: function() {
start = Date.now();
},
clockEndDate: function() {
end = Date.now();
duration = (end - start) / 1000;
},
getDuration: function() {
return duration;
}
};
})
.directive('postRepeatDirective', ['$timeout', 'TimeTracker', function($timeout, TimeTracker) {
return function(scope, element, attrs) {
if (scope.$last){
$timeout(function(){
TimeTracker.clockEndDate();
});
}
};
}]);
function getUsers(size) {
var users = [];
for (var i=0; i<size; i++) {
var user = {
name: 'User ' + i,
gender: Math.random() > 0.5 ? 'm' : 'w',
project: Math.random() > 0.25 ? 'fame' : 'idol',
secretagent: Math.random() > 0.95
};
users.push(user);
}
return users;
}
但是,我注意到随着项目数量的增加,性能明显下降。在大约 2500 个项目时,它确实变得太慢了。
我知道常见的建议是使用分页或自动滚动,但这并不是要为 ngRepeat 中的大列表寻找替代解决方案。您对提高性能有什么建议吗?
最佳答案
如果您计划对 数千 项进行 ng-repeat,那么您将不得不格外注意并尽可能优化每次迭代,这是无法回避的事实。
比如可以优化隐藏用户的逻辑。除了使用 ng-if,您还可以使用过滤器来删除不应显示的用户:
ng-repeat="user in users | filter:usersFilter | orderBy:'project'"
这样我们就可以更早地删除它们(甚至在我们对用户进行排序之前)。这比每次迭代都必须初始化一个指令要快得多,特别是因为 ng-if 创建一个新的子范围,这有点昂贵。
ng-switch 也是如此,它也会创建自己的子作用域。
这是一个修改后的 fiddle ,其中 ng-if 和 ng-switch 已被删除: http://jsfiddle.net/2z2e33em/
它产生相同的最终结果,而且它更快也就不足为奇了,因为我们现在已经删除了两个指令。但我认为它说明了此类更改如何对性能产生巨大影响(修改后的 fiddle 对我来说大约快 3 倍)。
关于javascript - AngularJS ng-repeat 性能和基准测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28215797/