Angular-嵌套的$scope将生成嵌套的$watcher

Angular - Nested $scope will produce nested $watchers?

本文关键字:嵌套 watcher scope Angular-      更新时间:2023-12-24

我遇到了性能问题,我想这是由于页面中有很多观察者(超过4000!!)。场景是一个(小的,大约5个)ng重复一次的项目列表,每个项目包含一周中每一天的另一个ng重复(所以是7),并且在每天容器中有1或2个输入字段。每天的元素都有自己的作用域和控制器,并在父元素的属性上进行一些监视,以便在子元素发生更改时更新父元素的状态。所以这是一个有点复杂的场景。。。想象一个议程视图,其中每天都有一些输入字段或按钮更新主范围中的相同属性,比如"选择/填写/单击10天"。

我从大约5000名观察者开始,现在减少到大约4000名,删除了一些过滤器,并切换到翻译一次指令,而不是translate(角度翻译)。

所以主要问题是:

如何进一步减少观看人数

是否每个子作用域都继承了父观察者,从而为每个观察者带来7x?如果我删除子项的控制器,将作业留给父项(将子项传递给函数),我会减少观察者的数量吗?这会是一个解决方案吗?任何帮助都将不胜感激。

根据我们的经验,观察者的数量不会导致速度问题。在过去的8个月里,我们在单个大型应用程序的开发中遇到的性能问题是由第三方组件运行缓慢引起的。

例如,我们有一个页面,它有两个拖放树,有14.600个观察者(因为这两个树中的项目数量都很高)。由于使用的组件angular ui树,我们遇到了性能问题,在打开页面时,树的大部分都崩溃了,我们减少了这些问题。

我们无法更改该组件,因为它是唯一一个具有在树之间拖放功能的组件,但在另一个页面中,我们有拖放功能;在简单列表之间拖放我们已经尝试了这两个组件:角度拖放和角度拖放列表。第一次有很多性能问题(大约有500个项目),而第二次运行非常快。在他关于github的文档中,"为什么是另一个拖放库?"你可以理解为什么它这么快,为什么另一个这么慢。

因此,我可以推测,第三部分的组件会给您带来真正的性能问题,而不是观察者。

在任何情况下,我们经常给观察者写一个像下面这样的检查,除非需要,否则不要运行代码。

$scope.$watch('variableToWatch', function(newValue, oldValue) {
    if (newValue === oldValue) {
        return;
    }
    ... watcher code ...
}

另一种减少html观察者的方法是使用一次性绑定。示例:

<div ng-if="::vm.user.loggedIn"></div>

与性能有关-我提出的一种模式是使用一个私有对象并分配一个函数的原型以便于访问。那么在任何函数、控制器、指令中。。。ect可以方便地访问其他函数、控制器、指令的原型。您可以像使用事件循环一样使用此模式,而不是使用观察者。而不是每个摘要周期都有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
    }
  }
}