Reputation: 105071
I was wondering whether I could gain any significant performance difference in my Angular app (specifically view processing) if I change ng-app
and ng-controller
attribute placement from i.e. body
to some inner-page block element with much smaller DOM subtree?
Suppose I have a very long page with huge amount of content, but only part of it is Angular powered. Everything else is either server generated which means it's somewhat static from the client-side PoV.
Would it be better to put ng-app/ng-controller
on only that subnode where Angular actually executes or would it be the same if I put them on body
element of this very long page?
Does Angular process the view only of the sub-DOM where ng-app/ng-controller
are defined or does it process the whole DOM anyway?
Is there any proof about this or even Angular documentation?
Upvotes: 3
Views: 542
Reputation: 49590
ng-app
really just specifies the root element on which Angular calls angular.bootstrap
. bootstrap
starts a "compilation" process, which is to say that it goes over each DOM element in the subtree of the root and collects directives from it and links them.
Right there, you can see the benefit of restricting the app to a smaller subtree of the DOM:
<input>
elements that should not be part of the app are not compiled/linked).The thing to remember is that it is the $digest cycle that is the significant source of performance problems/opportunities for optimizations - that is, the number of $watchers
and how fast the "$watchers"
are.
Upvotes: 1
Reputation: 4471
Theoretically/Potentially? Yes, as New Dev mentions, the bootstrap
function will have a larger DOM to run compile
on, which would take longer than compiling a smaller tree.
Practically? Probably not. But your best bet is to benchmark your own page.
As an experiment, you can try the following. I generated a simple random DOM and injected it into a JSFiddle with console.time
starting at script load, and ending when the controller is ready. There's a small sub-tree beside (as a sibling) a much larger, 5000-node tree.
Here's the fiddle wrapping the entire body: http://jsfiddle.net/gruagq8d/
And here's the fiddle where only the small subset is used: http://jsfiddle.net/h0hod2j8/
For me, running either of those fiddles repeatedly converges on about 260ms.
I've also tried running similar code on real webpage sources, such as StackOverflow itself, and found the same results (however I did not publish any of these because publishing other people's real pages to JSFiddle does not feel proper without permission) - you can try this for yourself pretty trivially.
Admittedly, this doesn't follow great benchmarking methodology, but if wrapping lots of additional DOM nodes caused significant different performance I'd still expect at least some difference in these.
I don't think that the additional compile time is an issue; for small DOMs it's obviously fast, and for large DOM is very relevant compared to the time it takes your browser to build the DOM in the first place.
All said, as mentioned before, your best option is to try to run similar benchmarks with your own page.
EDIT: Modifying the same benchmark to test digest cycles shows that there's no significant difference in those as well:
Wrapping minimal: http://jsfiddle.net/fsyfn1ee/
Wrapping whole DOM: http://jsfiddle.net/04tdwxhp/
Upvotes: 1
Reputation: 6143
Official docs say that only portion that is wrapped into ng-app
directive is compiled.
If the ng-app directive is found then Angular will:
- load the module associated with the directive.
- create the application
- injector compile the DOM treating the ng-app directive as the root of the compilation. This allows you to tell it to treat only a portion of the DOM as an Angular application.
This is pretty much expected as Angular allows to have several Angular modules controlling independent parts of one page (requires manual bootstrapping as pointed by Josiah Keller in comments). And their scopes will not interfere.
However adding extra static html (not angular bound) affect performance only at bootstrap. Yes angular has to compile all that elements at bootstrap to learn whether it should deal with them later.
But run-time performance is mostly affected by $watch
s. Implicit form of creating them is to do bindings. So the more bindings you have overall, the longer each $digest
cycle takes. And gives a general feeling of slow app. I've met a sensible threshold of 2k watches for modern browser/CPUs
Upvotes: 0