AngularJS digest postDigestQueue

Ant*_*EVE 19 javascript angularjs

我们的一个页面很重.为了减少我们的观察者数量并加速角度摘要周期,我们使用了大量的On-Time-Binding语法::.我们还使用angular-bind-notifier来避免对此页面上的表达式进行不必要的监视.

这种策略使我们能够大大减少角度消化周期.

但是这种策略有一个缺点:它在成功评估后使用$$postDigest(postDigestQueue)unwatch表达式.

所以呢 ?

在摘要的最后,角度将穿过postDigestQueue.由于我们使用了大量的On-Time-Binding表达式,因此我们postDigestQueue可以增长到超过10万个排队任务.

问题是angular使用以下代码循环队列:

while (postDigestQueue.length) {
  try {
    postDigestQueue.shift()();
  } catch (e) {
    $exceptionHandler(e);
  }
}
Run Code Online (Sandbox Code Playgroud)

shift方法删除零点索引处的元素并将连续索引处的值向下移动,然后返回删除的值.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift

是的,Array.prototype.shift()当阵列中有很多元素时,这是一个非常昂贵的调用.

由于这个原因,我们的摘要周期有时会超过20秒.

当我们使用以下代码更改以前的代码时,它会更快:

for (var i = 0; i < postDigestQueue.length; i++) {
  try {
    postDigestQueue[i]();
  } catch (e) {
    $exceptionHandler(e);
  }
}
postDigestQueue.length = 0;
Run Code Online (Sandbox Code Playgroud)

有没有理由他们这样做?我们不应该使用那么多的一次性绑定吗?

我可以看到一个原因:如果一个任务在队列中添加了一个需要任务.有可能吗?($$postDigest是一个私人队列)答案是使用pop而不是shift如果执行顺序不重要,但是它?

编辑:顺序似乎很重要,因为postDigestQueue它与动画一起使用.

如果有人对可能的官方跟进感兴趣,我在问题跟踪器上打开了一个问题.

Ant*_*EVE 0

Angular 团队合并了将在下一个1.5.x版本中进行的性能改进: https://github.com/angular/angular.js/commit/cb2f8c0d75bde9ac91f4129e871ff4a8301871f3

这将加快摘要周期,特别是当您使用$$postDigest像 Angular-bind-notifier 这样的东西时。