3

我想知道如果我将 ie 更改ng-appng-controller属性放置body到具有更小的 DOM 子树的一些内页块元素,是否可以在我的 Angular 应用程序(特别是视图处理)中获得任何显着的性能差异?

假设我有一个非常长的页面,其中包含大量内容,但其中只有一部分是 Angular 驱动的。其他一切都是服务器生成的,这意味着它在客户端 PoV 中有些静态。

ng-app/ng-controller最好只放在Angular实际执行的那个子节点上,还是如果我把它们放在body这个非常长的页面的元素上会不会更好?

Angular 是只处理ng-app/ng-controller定义的子 DOM 的视图,还是处理整个 DOM?

有没有关于这个甚至 Angular 文档的证据?

4

3 回答 3

1

ng-app实际上只是指定 Angular 调用的根元素angular.bootstrapbootstrap开始一个“编译”过程,也就是说,它遍历根的子树中的每个 DOM 元素,并从中收集指令并链接它们。

在那里,您可以看到将应用程序限制在 DOM 的较小子树中的好处:

  1. 编译过程稍快
  2. 编译更少的指令(例如<input>,不应该成为应用程序一部分的元素不会被编译/链接)。

要记住的是,$digest 循环是性能问题/优化机会的重要来源——即优化的数量$watchers和速度"$watchers"

于 2015-08-01T02:22:39.820 回答
1

理论上/潜在的?是的,正如 New Dev 所提到的,该bootstrap函数将有一个更大的 DOM 来运行compile,这比编译一个较小的树需要更长的时间。

几乎?可能不是。但最好的选择是对自己的页面进行基准测试。

作为实验,您可以尝试以下方法。我生成了一个简单的随机 DOM 并将其注入到 JSFiddle 中,console.time从脚本加载开始,到控制器准备就绪时结束。在一个更大的 5000 节点树旁边(作为兄弟)有一个小的子树。

这是包裹整个身体的小提琴:http: //jsfiddle.net/gruagq8d/

这是只使用小子集的小提琴:http: //jsfiddle.net/h0hod2j8/

对我来说,重复运行这些小提琴中的任何一个都会在大约 260 毫秒内收敛。

我也尝试在真实的网页源上运行类似的代码,例如 StackOverflow 本身,并发现了相同的结果(但是我没有发布任何这些,因为未经许可将其他人的真实页面发布到 JSFiddle 感觉不合适) - 你可以自己试试这个很简单。

诚然,这并没有遵循很好的基准测试方法,但如果包装大量额外的 DOM 节点会导致显着不同的性能,我仍然希望这些至少有一些差异。

我认为额外的编译时间不是问题。对于小型 DOM,它显然很快,而对于大型 DOM,与您的浏览器首先构建 DOM 所花费的时间相比,它非常重要。

总而言之,如前所述,您最好的选择是尝试使用您自己的页面运行类似的基准测试。

编辑:修改相同的基准测试摘要周期表明这些也没有显着差异:

最小包装:http: //jsfiddle.net/fsyfn1ee/

包装整个 DOM:http: //jsfiddle.net/04tdwxhp/

于 2015-08-04T21:15:28.097 回答
0

官方文档说只有包含在ng-app指令中的部分被编译。

如果找到 ng-app 指令,那么 Angular 将:

  • 加载与指令关联的模块。
  • 创建应用程序
  • 注入器编译 DOM,将 ng-app 指令视为编译的根。这允许您告诉它仅将 DOM 的一部分视为 Angular 应用程序。

这是非常符合预期的,因为 Angular 允许多个 Angular 模块控制一个页面的独立部分(需要手动引导,正如 Josiah Keller 在评论中指出的那样)。他们的范围不会干扰。

但是,添加额外的静态 html(不是角度限制)仅在引导时影响性能。是的,Angular 必须在引导程序中编译所有这些元素,以了解它是否应该稍后处理它们。
但运行时性能主要受$watchs 的影响。创建它们的隐式形式是进行绑定。因此,您总体拥有的绑定越多,每个$digest周期所需的时间就越长。并给人一种慢应用的普遍感觉。对于现代浏览器/CPU,我已经达到了 2k 手表的合理阈值

于 2015-08-01T02:16:45.473 回答