与DOM

时间:2015-06-19 10:00:08

标签: angularjs performance dom ng-controller ng-app

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

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

ng-app/ng-controller仅放在Angular实际执行的子节点上会更好吗?如果我将它们放在这个非常长的页面的body元素上它会不会相同?

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

是否有关于此甚至Angular文档的证据?

3 个答案:

答案 0 :(得分:1)

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

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

  1. 编译过程稍快一点
  2. 编译较少的指令(例如,<input>不应该成为应用程序一部分的元素未编译/链接。
  3. 要记住的是,$摘要周期是性能问题/优化机会的重要来源 - 即$watchers的数量和"$watchers"的速度。

答案 1 :(得分:1)

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

实际上?可能不是。但最好的办法是对自己的页面进行基准测试。

作为实验,您可以尝试以下操作。我生成了一个简单的随机DOM,并在脚本加载时将其注入一个带有console.time的JSFiddle,并在控制器就绪时结束。旁边(作为兄弟姐妹)有一个小的子树,一个更大的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/

答案 2 :(得分:0)

Official docs表示只编译包含在ng-app指令中的部分。

  

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

     
      
  • 加载与指令关联的模块。
  •   
  • 创建应用程序
  •   
  • inject编译DOM,将ng-app指令作为根目录   汇编。这允许你告诉它只处理一部分   DOM作为Angular应用程序。
  •   

这是非常期待的,因为Angular允许有几个Angular模块控制一个页面的独立部分(需要Josiah Keller在评论中指出的手动引导)。他们的范围不会干涉。

但是,添加额外的静态html(不是角度限制)只会影响bootstrap的性能。是angular必须在bootstrap编译所有元素,以了解它是否应该在以后处理它们。
但运行时性能主要受$watch的影响。创建它们的隐式形式是进行绑定。因此,总体而言,绑定越多,每个$digest周期所需的时间就越长。并给出一个缓慢的应用程序的一般感觉。对于现代浏览器/ CPU,我已经达到了明智的2k手表门槛