我目前正在处理一个有500行的表。每行有5个单元格。每个单元格都是一个指令。渲染此表大约需要3秒钟,它会锁定浏览器。
99%的时间用在"解析HTML"我假设解析HTML指令的函数。 (当我向下滚动时,有许多Parse HTML函数。我猜测它的大约2500,无法找到计算它的方法。)
一个plnkr链接,您可以使用chrome dev工具查看问题(大部分时间都在解析HTML中):http://plnkr.co/edit/UouSapMYGgCNy7jEhlR6?p=preview
如果不手动连接每行的HTML字符串,我将如何进行优化呢?
// Code goes here
angular
.module('app', [])
.directive('cellOne', function() {
return {
scope: {
data: '='
},
templateUrl: 'cell.html'
};
})
.directive('cellTwo', function() {
return {
scope: {
data: '='
},
templateUrl: 'cell2.html'
};
})
.directive('row', function($compile) {
return {
compile: function compile() {
return {
pre: function preLink(scope, element) {
var html = '';
html += '<cell-one data=row[0]></cell-one>'
html += '<cell-two data=row[1]></cell-two>'
html += '<cell-one data=row[2]></cell-one>'
html += '<cell-two data=row[3]></cell-two>'
html += '<cell-two data=row[4]></cell-two>'
var el = angular.element(html);
var linkFunction = $compile(el);
element.append(el);
linkFunction(scope);
}
}
}
}
})
.controller('controller', function($scope) {
$scope.data = [];
// Fill the data map with random data
$scope.refresh = function() {
for (var i = 0; i < 500; ++i) {
$scope.data[i] = {};
for (var j = 0; j < 5; ++j) {
$scope.data[i][j] = Math.random();
}
}
}
$scope.refresh()
});
答案 0 :(得分:1)
一个众所周知的事实是,当你有超过2000个观察者(负责处理你的数据绑定)时,Angular会出现性能问题。在你的情况下,你至少有2500。
减少数据绑定的数量肯定会有所帮助。 Angular最近引入了一次性数据绑定,如果绑定的数据不是完全动态的,您可以利用它。
我建议您查看Speeding up AngularJS apps with simple optimizations以获取更多信息。
答案 1 :(得分:1)
正如贾斯汀所提到的,减少手表有助于和$编译是非常昂贵的。当我看到这段代码时,有两件具体事情会跳出来:
1)使用&#39; =&#39;。这是双向绑定,但如果cellOne和cellTwo指令不会更改行,则会为每个单元格创建不必要的监视。 (请注意,即使在模板中进行插值时使用:: data语法,也会设置这些手表)。改为&#39;&amp;&#39;是一个快速的胜利。
2)每行都运行$ compile。 $ compile(和$ parse)相对昂贵。不知道你为什么不用模板参数来做这件事,但如果由于某种原因你需要使用$ compile,只需调用一次并缓存链接函数,而不是在指令的每个实例中调用$ compile。链接 - &gt;快..... $ compile - &gt;慢(相对)。在这两个优化中,这一个应该产生最大的影响。
Here is a plunk with these optimizations applied用于比较目的。
angular
.module('app', [])
.directive('cellOne', function() {
return {
scope: {
data: '&'
},
templateUrl: 'cell.html'
};
})
.directive('cellTwo', function() {
return {
scope: {
data: '&'
},
templateUrl: 'cell2.html'
};
})
.directive('row', function() {
return {
template: '<cell-one data=row[0]></cell-one>' +
'<cell-two data=row[1]></cell-two>' +
'<cell-one data=row[2]></cell-one>' +
'<cell-two data=row[3]></cell-two>' +
'<cell-two data=row[4]></cell-two>'
}
})
<p>cell1: {{:: data() }}</p>