我遇到性能问题,我认为由于页面中有很多观察者(超过4000 !!)。该场景是ng-repeat中的一个(小的,约5个)项目列表,每个项目包含每周一天的另一个ng-repeat(所以7),并且在每天容器中有1或2个输入字段。每天的元素都有自己的范围和控制器,有些监视父级的属性,以便在子级更改时更新父级状态。所以有点复杂的情况...想象一个议程视图,其中每天作为一些输入字段或按钮更新主范围内的相同属性,如“10天选择/填充/点击”。
我从大约5000名观察者开始,现在减少到大约4000个删除一些过滤器并切换到翻译指定翻译(angular-translate)。
所以主要的问题是:
如何进一步减少观察人数?
是否每个儿童范围都继承了父母观察者,每个观察者产生7倍?如果我删除孩子的控制器,将作业留给父母(将子项目传递给函数),我会减少观察者的数量吗?这可能是一个解决方案吗?任何帮助都是值得赞赏的。
答案 0 :(得分:1)
根据我们的经验,观察者数量不会引起速度问题。我们在一个大型应用程序开发的最后8个月遇到的性能问题是由于第三部分组件速度缓慢造成的。
例如,我们有一个带有两个拖放树的页面,其中有14.600个观察者(因为两棵树中的项目数量很大)。由于使用了组件angular-ui-tree,我们遇到了性能问题,并且我们减少了它们打开页面,大部分树都崩溃了。
我们无法更改该组件,因为它是唯一一个在树之间拖放功能的组件,但是在另一个我们有拖放的页面中。在简单列表之间我们尝试了这两个组件:angular-dragdrop和angular-drag-and-drop-lists。第一个有很多性能问题(大约有500个项目)而第二个运行真的非常快。在他关于github的文档中,"Why another drag & drop library?"部分你可以理解为什么它如此之快以及为什么另一个如此之慢。
所以,我可以推测第三部分的组件会给你带来真正的性能问题,而不是观察者。
在任何情况下,我们经常使用下面的支票给我们的观察者写信,除非需要,否则不要运行代码。
$scope.$watch('variableToWatch', function(newValue, oldValue) {
if (newValue === oldValue) {
return;
}
... watcher code ...
}
从html减少观察者的另一种方法是使用one-time-binding。 例如:
<div ng-if="::vm.user.loggedIn"></div>
答案 1 :(得分:0)
与性能相关... - 我提出的一种模式是使用私有对象并分配函数的原型以便于访问。然后在任何函数,控制器,指令......你可以轻松访问其他函数,控制器,指令的原型。而不是使用观察者,您可以像事件循环一样使用此模式。而不是每个消化周期角度运行300+观察者。使用这种模式只会触发函数调用。
此模式的一个示例
var private = {} //accesable to entire app
var app = angular.module('some-app',[])
.controller('someCtrl',['$scope',someCtrl])
.directive('someDirective',someDirective);
function someCtrl($scope){
private.someCtrl = someCtrl.prototype
someCtrl.prototype.update = function(someDate){
//do something....
//access to someCtrl arguments
$scope.something = someDate
}
}
function someDirective(){
var someCtrlProto = private.someCtrl;
return{
link:function(scope ,elm ,attr){
elm[0].addEventListener('click',fucntion(){
someCtrlProto.update(someData)
});
//or
elm[0].addEventListener('click',someCtrlProto.update) //to trigger someCtrl.update from here
}
}
}
&#13;