我想知道如果我将ng-app
和ng-controller
属性展示位置从body
更改为某个内部,我是否可以在我的Angular应用程序(特别是视图处理)中获得任何显着的性能差异具有更小DOM子树的页面块元素?
假设我有一个包含大量内容的非常长的页面,但只有一部分是Angular驱动的。其他一切都是服务器生成的,这意味着它与客户端PoV有点静态。
将ng-app/ng-controller
仅放在Angular实际执行的子节点上会更好吗?如果我将它们放在这个非常长的页面的body
元素上它会不会相同?
Angular是否只处理定义了ng-app/ng-controller
的子DOM的视图,还是处理整个DOM?
是否有关于此甚至Angular文档的证据?
答案 0 :(得分:1)
ng-app
实际上只是指定了Angular调用angular.bootstrap
的根元素。 bootstrap
开始编辑"进程,也就是说它遍历根的子树中的每个DOM元素,并从中收集指令并链接它们。
就在那里,您可以看到将应用程序限制为DOM的较小子树的好处:
<input>
不应该成为应用程序一部分的元素未编译/链接。要记住的是,$摘要周期是性能问题/优化机会的重要来源 - 即$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手表门槛