AngularJS - Why is ng-bind faster than expressions? - angularjs

From this question and this answer, it seems that using expressions will cause the value to be evaluated from scratch every time. But I've searched the documentation and tutorials, and I haven't found a reference for this statement.
In my mind, both are wrapped in a $watch() and so when the $digest() cycle runs it will see whether the value inside ng-bind or {{}} has changed.
On performance, why is ng-bind better than {{}} as has been suggested, and where's the reference?

Details like this aren't always available in the documentation - you have to read the source. I took a peek and it seems that (as of 2014-11-24) they both work in a very similar way. Both cause a single directive to be instantiated to change the value when needed (the curly interpolation directive is generated on the fly).
Both directives evaluate the expressions involved on every $digest just like everything else. The main difference is that while ng-bind doesn't do any further processing on the value, with curlies, the entire interpolated text is recalculated on every digest. Essentially a string is built using $interpolate and that is compared with the previous value (this happens within the bowels of $digest). Neither way will update the DOM if the value (either the plain value with ng-bind or the interpolated result with curlies) hasn't changed.
To me the accepted answer on that question is a more compelling reason to use ng-bind, i.e. you can use it to prevent a visible flash of the template tags before Angular loads and compiles them, without resorting to hacks like ng-cloak.
Depending on variables there may also be cases where curly interpolation is actually more performant. One situation I can think of is when using ng-bind instead of interpolation requires you to create a lot of otherwise redundant <span> elements, and that tips the scales in the other direction. An interpolation expression also causes a single watcher to be created for the entire string independent of how many variables you use, as opposed to ng-bind which creates one watcher for each instance.
But as always, don't optimize for performance early, and if you do, profile to find out which part really matters.

The major difference between ng-bind and {{}} is that ng-bind creates a watcher for variable passed to it(i.e. name as in above example), while curly brackets({{}}) will (store the entire expression in memory i.e. }perform dirty-checking and refreshing the expression in every digest cycle even if it is not required.
ng-bind will only apply when the value passed is changing actually.
for more details refer below link:
http://www.ufthelp.com/2015/11/difference-between-and-ng-bind-in.html

Related

is mixing one time with one way binding in Angualrjs possible inside ng-if?

I'm using latest AngluarJS release,
I was wondering if I can combine one time with one way binding in one expression inside ng-if directive , some like that:
ng-if="(vm.isUnix) && (::vm.isGnsEnabled)"
The line above throws an error, not working
This is not possible. The one time binding token must come first and will mean that once the expression is stable it will no longer be watched.
ng-if="::vm.isUnix && vm.isGnsEnabled"
If vm.isUnix can change during the lifetime of your component and you need to reflect this change in the view, there is no way to prevent a watcher for this expression.
Edit: basically one-time binding is for the entire expression, not for individual properties inside the expression.

Does {{'any'}} have a watcher? Is {{::'any'}} a performance improvement?

I am going to improve the perfomance of my angular app. So I decided to use {{::variable}} more often (>angular 1.3). For translations I used the writting {{'key.header'|translate}}.
Is a performance improvement possible if i use {{:'key.header'|translate}} or does angular know that these strings won't change?
Thank you
The only way to indicate to angular that your string would not change is using {{::variable}}. And yes, it's a performance improvement because you are telling to angular to evaluate that expression once and then ignore it (avoiding two-way binding) and never watch it again. So,
less watchers = better performance
NOTE:
You can set an angular expression using ::, only if your expression wouldn't be changed over the time. In your case(about your comment), if you want to use that expression to get a translated version on a string, you should not use it then, because the user may changes the language any time and it needs got changed.
Conclusion
You should use :: over angular expressions that wouldn't be changed over the time. :: is a way to declare a constant and reduce your watchers, getting a better performance.

Maximise effectiveness of one-time bindings

I'm currently working on the performance of an angularJS application, and was wondering if there is any difference in performance between these two examples:
http://plnkr.co/edit/T5aHybkkCoF5MDzXX2Kk?p=preview
http://plnkr.co/edit/sX2ffPPOQTyFbb70elwp?p=preview
The difference is that in the first example, in the file 'testdirective.html' the ng-if boolean is not bound in a one time expression. However, it is already bound as a one-time binding in the 'index.html'.
<div ng-if="enabled">
vs
<div ng-if="::enabled">
Is using a one-time expression in the directive as well as in the index file better for the performance?
Thanks!
Yes, there will be a performance difference (although negligible in this case).
The directive doesn't take into account if the value passed to it was one-time bound or not, so if the directive's template doesn't use a one-time binding it will register a new watcher.
The cost of running this watcher during the digest cycle will bascially be the difference in performance in the two examples.
An extra note on your example that doesn't really touch the question is that the following two cases will behave the same:
<testdirective enabled="::true"></testdirective>
And
<testdirective enabled="true"></testdirective>
In the second case true will be treated as a constant that cannot change and the registered watcher will be removed, just like with a one-time binding.

Angular translate attribute vs filter

Which of these two is better?
<span translate="key">Key</span>
or
<span>{{'key' | translate}}</span>
They are both good and work fine but in first case I must fill the content of the element.
Using the attribute is better performance-wise, especially if you intend to use translations on elements that will be inside ngRepeats. This is because the way filter work internally.
Every time there is a digest cycle, angularjs reloads all the expressions containing filters. This is because angular can't possibly know if a filter has changed or not. What this means is that, even if the key of the translation has not changed, but some other value on the scope has, angular will look through every translation and translate it again, just to come to the conclusion that they all remain the same.
Attributes are smarter, because the developer of the directive has explicit control over when it should re-render and what watcher should be created.
Edit: And as far as I know, there is no need to fill the content in the first use-case. You can just leave it empty.

Too many listeners and slow $compile, need performance tips or something between two-way binding and one-time binding

Sorry, I don't have a live example, I'm looking for performance advice.
I've finally hit my first performance problem with angular, I have a pretty complex UI and in it, I have a directive with about 3 nested repeats that use directives, in every level the directive uses scope: true and using bindToController syntax.
The data source is not that big, but every repeat ends up being between 30-100 watchers (I'm using this snippet to count the watchers)
I'm calling $compile on the top directive and it takes way over a second (!) to show the HTML (it ends up having a few hundred listeners), ng-if and ng-class and other custom directives, it quickly adds up.
I've added one-time bindings wherever I could, but I'm still at way over a 1000 in total and I guess that can slow things down?
I've ran CPU profilers in different browsers, drilled as deep as possible and I never saw my code taking up and significant time, all I see it jquery/angular taking a long long time, but none of the functions inside show any significant self time.
If I open that 800ms elemData.handle, all I see is angular's $scope.eval, compileDirectives and a bunch of other angular stuff in a deep tree.
Could using scope: true be the culprit? Would complex directives perform better if they use an isolate scopes?
Maybe there are advanced methods I don't know to use one-time bindings? Or something between two-way and one-way?
EDIT: for posterity, this is what happened: I managed to replace my isolate scope directives on the inner-most ng-repeat level with simple ng-includes, the functionality is the same, but execution time is 1/1000. I don't think I'll ever really know why the difference was so huge, I never had many items in the ng-repeat, but the code now runs in 1ms :)
Use $destroy events to clean up event watchers
Use one-way-binding everywhere what you can't change manually (ng-repeat, ng-options)
In templates try to avoid functions that will return value. Simple assignment not needed to be compiled but function will run each $digest (ng-if="ctrl.isDataLiading()" slower then ng-if="ctrl.isDataLoaded")
In list items with a lot of ng-repeat avoid filters that will recount and run collection watchers on arrays that is taking great portion of performance - instead use ng-if to remove filtered items
When I was implementing tree structure that can be like expanded to see child nodes (list with + option) I struggled with such problem. Above approach made functionality better but speed did not rise a lot.
In common words all my answer means: angular populates too many watchers, get rid of them

Resources