$eval is used internally by angular when resolving angular expressions, such as {{variable}}
. Without seeing any of your code, it's hard to tell what expressions are using resources unnecessarily, but usually too large or nested ng-repeat
s (or many ng-
directives included within an ng-repeat
) are a code smell.
Angular uses dirty checking to evaluate these expressions (for lack of a better option) - that means that every time you create a binding with the {{}}
syntax, it creates an implicit $watch expression getting that value, that will be called every digest cycle to see if the value has changed (on which change the relevant parts of the DOM are regenerated).
Here's one optimization I've used successfully in the past:
most of the time, when you bind a value with {{}}
, you don't actually expect the value to change (like a label), and this 2-way data binding is completely superflous. Since angular version 1.3 you have the options to create one-time bindings with the ::
syntax:
One-time expressions will stop recalculating once they are stable, which happens after the first digest if the expression result is a non-undefined value
which eliminates the corresponding performance overhead of such bindings. (If you're using older angular versions, external libraries can mimick this behaviour, such as bindonce.)
Here are some additional tools I've found useful while profiling/optimizing angular apps:
- Batarang, a chrome extension "for debugging and profiling angular applications"
This stackoverflow answer, giving a neat solution for counting how many watch expressions are active on your page. A rule of thumb is that if you're above 2000, you'll start noticing performance issues, and you should think about changing your architecture - employ lazy loading mechanisms, reconsider whether you truly need all the bindings etc.
In production environments disabling the default "debug mode" of angular can also help with performance.