无法减少 ng-repeat 中的观察者数量

Nuz*_*zob 6 performance angularjs angularjs-ng-repeat

出于性能目的,我想从我的 ng-repeat 中删除双重数据绑定(因此,关联的观察者)。

它加载了 30 个项目,这些数据一旦加载就是静态的,因此不需要双重数据绑定。

问题是,无论我如何操作,该页面上的观察者数量都保持不变。

让我们说:


<div ng-repeat='stuff in stuffs'>
   // nothing in here
</div>
Run Code Online (Sandbox Code Playgroud)

观察者数量为211(该页面上还有其他绑定,不仅是 ng-repeat)


<div ng-repeat='stuff in ::stuffs'>
   // nothing in here
</div>
Run Code Online (Sandbox Code Playgroud)

观察者数量仍然是211(如果我理解正确的话应该是210),但是等等:


<div ng-repeat='stuff in ::stuffs'>
    {{stuff.id}}
</div>
Run Code Online (Sandbox Code Playgroud)

观察者数量现在是241(好吧,211 观察者 + 30 个东西 * 1 观察者 = 241 观察者)


<div ng-repeat='stuff in ::stuffs'>
    {{::stuff.id}}
</div>
Run Code Online (Sandbox Code Playgroud)

关注人数还是241!!!:: 不应该删除关联的观察者吗??


<div ng-repeat='stuff in ::stuffs'>
    {{stuff.id}}  {{stuff.name}}  {{stuff.desc}}
</div>
Run Code Online (Sandbox Code Playgroud)

还是241 ...


这些例子真的是在我的应用程序中制作的,所以这些数字也是真实的。

真正的 ng-repeat 比这里的示例复杂得多,我的页面上有大约 1500 个观察者。如果我删除它的内容(如示例中所示),我会下降到大约 200 个观察者。那么我该如何优化它呢?为什么 :: 似乎不起作用?

谢谢你为我解惑...

sbe*_*lin 3

很难弄清楚您的具体情况的确切问题是什么,也许提供一个孤立的示例是有意义的,以便其他人可以提供帮助。

结果可能取决于您如何计算观察者。我从这里采取了解决方案。

这是一个按预期工作的Plunker 示例::(在 中添加或删除ng-repeat):

超文本标记语言

<!DOCTYPE html>
<html ng-app="app">
  <head>
    <script data-require="angular.js@1.5.6" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body ng-controller="mainCtrl">
    <div>{{name}}</div>

    <ul>
      <li ng-repeat="item in ::items">{{::item.id}} - {{::item.name}}</li>
    </ul>

    <button id="watchersCountBtn">Show watchers count</button>
    <div id="watchersCountLog"></div>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

JavaScript

angular
  .module('app', [])
  .controller('mainCtrl', function($scope) {
    $scope.name = 'Hello World';

    $scope.items = [
      { id: 1, name: 'product 1' },
      { id: 2, name: 'product 2' },
      { id: 3, name: 'product 3' },
      { id: 4, name: 'product 4' },
      { id: 5, name: 'product 5' },
      { id: 6, name: 'product 6' },
      { id: 7, name: 'product 7' },
      { id: 8, name: 'product 8' },
      { id: 9, name: 'product 9' },
      { id: 10, name: 'product 10' }
    ];
  });

function getWatchers(root) {
  root = angular.element(root || document.documentElement);
  var watcherCount = 0;

  function getElemWatchers(element) {
    var isolateWatchers = getWatchersFromScope(element.data().$isolateScope);
    var scopeWatchers = getWatchersFromScope(element.data().$scope);
    var watchers = scopeWatchers.concat(isolateWatchers);
    angular.forEach(element.children(), function (childElement) {
      watchers = watchers.concat(getElemWatchers(angular.element(childElement)));
    });
    return watchers;
  }

  function getWatchersFromScope(scope) {
    if (scope) {
      return scope.$$watchers || [];
    } else {
      return [];
    }
  }

  return getElemWatchers(root);
}

window.onload = function() {
  var btn = document.getElementById('watchersCountBtn');
  var log = document.getElementById('watchersCountLog');

  window.addEventListener('click', function() {
    log.innerText = getWatchers().length;
  });
};
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。