Since all watches are evaluated on every $digest, keeping their number low is a good perf practice. To rephrase the question title, is there a perf penalty for declaring either a variable or method on $scope inside a controller, when those aren't being referenced by related template (if there is a penalty one could declare those as local variable on controller object instead).
Asked
Active
Viewed 458 times
2
-
Yes there is. Angular triggers a $digest cycle every time anything in the scope changes (dirty/clean check). So it has to loop over every variable in your scope and check if it changed. – Sergiu Paraschiv Jan 18 '14 at 19:05
-
1Note that AngularJS doesn't do a $digest anytime something changes, it'll $digest anytime the scope is $apply'd. – Philipp Gayret Jan 18 '14 at 19:13
-
@SergiuParaschiv That's wrong. **First**, A digest happens only when it's being triggered ( mostly by directives / services ). **Second**, only registered watchers are being checked not the whole scope object. – Ilan Frumer Jan 18 '14 at 19:20
-
OK, sorry about the misunderstanding. It triggers a $digest cycle every time anything in the scope is applied. It does however loop over the whole scope and checks if anything changed. – Sergiu Paraschiv Jan 18 '14 at 19:23
-
3Again, it loops over the **$$watchers** list not over the entire scope. I never heard the angular guys say you should avoid keeping unnecessary data on the scope they only warn about $watchers. – Ilan Frumer Jan 18 '14 at 19:24
-
1Here's [a fiddle](http://jsfiddle.net/KQ4uy/1/) that might clear up some of the confusion. It shows every time a $digest is run and it changes two scope variables- one, every quarter second, done outside angular (using `setInterval`) and one, every 2 seconds, "inside Angular" using Angular's $interval- so it's done within an apply. Only the Angular aware undate triggers a $digest, but both bindings are then updated once the digest occurs. – KayakDave Jan 18 '14 at 19:29
-
2After actually reading the code I can say I was terribly wrong. Angular does not dirty check everything on the scope. It cares about the watchers only. – Sergiu Paraschiv Jan 18 '14 at 19:32
1 Answers
0
When you place something on $scope
, it can be watched. You can $watch
anything on the scope perfecly fine, even if it is not on a template.
Is there a performance penalty? AngularJS usually compares references when you watch objects, and only compares the watched objects, not everything on the scope. So unless you are doing a deep compare on a very large object or array that you are watching, it should't take noticeable time.
For testing performance and seeing if your changes are slowing anything down, you can use the AngularJS Batarang.

Community
- 1
- 1

Philipp Gayret
- 4,870
- 1
- 28
- 34
-
1Just to add to this, you can watch things not on the scope by returning it from a function passed as the first argument to $watch. – Michal Charemza Jan 18 '14 at 21:33