410

I was in one of the angular presentation and one of the person in the meeting mentioned ng-bind is better than {{}} binding.

One of the reason, ng-bind put the variable in the watch list and only when there is a model change the data get pushed to view, on the other hand, {{}} will interpolate the expression every time (I guess it is the angular cycle) and push the value, even if the value changed or not.

Also it is said that, if you have not much data in on the screen you can use {{}} and the performance issue will not be visible. Can someone shed some light on this issue for me?

John Slegers
  • 45,213
  • 22
  • 199
  • 169
Nair
  • 7,438
  • 10
  • 41
  • 69
  • 15
    ["It is preferable to use `ngBind` instead of `{{ expression }}` if a template is momentarily displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an element attribute, it makes the bindings invisible to the user while the page is loading."](https://docs.angularjs.org/api/ng/directive/ngBind) -- but nothing is mentioned about performance. – Blazemonger Oct 28 '14 at 17:58
  • 3
    Could you please check, if my answer is the better – Konstantin Krass Feb 26 '15 at 09:13
  • {{}} in my opinion is not practical, the viewer will see your tag before data is loaded completely. I wonder if Angular team is ever going to fix this issue. – OKEEngine May 29 '15 at 01:21
  • 2
    @Blazemonger: Can't you just include ng-cloak attribute to prevent templates being momentarily displayed? – supershnee Dec 17 '15 at 23:22

12 Answers12

546

Visibility:

While your angularjs is bootstrapping, the user might see your placed brackets in the html. This can be handled with ng-cloak. But for me this is a workaround, that I don't need to use, if I use ng-bind.


Performance:

The {{}} is much slower.

This ng-bind is a directive and will place a watcher on the passed variable. So the ng-bind will only apply, when the passed value does actually change.

The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not necessary.


I am currently building a big single page app (~500 bindings per view). Changing from {{}} to strict ng-bind did save us about 20% in every scope.$digest.


Suggestion:

If you use a translation module such as angular-translate, always prefer directives before brackets annotation.

{{'WELCOME'|translate}} => <span ng-translate="WELCOME"></span>

If you need a filter function, better go for a directive, that actually just uses your custom filter. Documentation for $filter service


UPDATE 28.11.2014 (but maybe off the topic):

In Angular 1.3x the bindonce functionality was introduced. Therefore you can bind the value of an expression/attribute once (will be bound when != 'undefined').

This is useful when you don't expect your binding to change.

Usage: Place :: before your binding:

<ul>  
  <li ng-repeat="item in ::items">{{item}}</li>
</ul>  
<a-directive name="::item">
<span data-ng-bind="::value"></span>

Example:

ng-repeat to output some data in the table, with multiple bindings per row. Translation-bindings, filter outputs, which get executed in every scope digest.

Drewness
  • 5,004
  • 4
  • 32
  • 50
Konstantin Krass
  • 8,626
  • 1
  • 18
  • 24
  • True, same thing here, how I noticed this is just to use in Google Chrome Batarang extension and check "Performance" tab with app using {{}} and app using ng-bind – pauldcomanici May 05 '14 at 13:15
  • 32
    this is a better answer – NimChimpsky May 15 '14 at 11:20
  • wanted to upvote but you got 808 points which is pretty cool :) – tmaximini May 22 '14 at 09:37
  • Does it make sense now with Angular 1.3 which has bindOnce to do something like this: ng-bind-html="::User.username" ??? – misaizdaleka Oct 17 '14 at 11:27
  • Sure, but only if you dont expect the User.username to change. This will avoid the additional watcher on that binding. – Konstantin Krass Oct 17 '14 at 12:10
  • 14
    From what I can tell from the source (as of 2014-11-24), curly interpolation is handled just like a directive (see addTextInterpolateDirective() in ng/compile.js). It also uses $watch so the DOM is not touched if the text doesn't change, it does not "dirty check and refresh" it on every $digest as you claim. What is done on every $digest though is that the interpolated result string is calculated. It's just not assigned to the text node unless it changes. – Matti Virkkunen Nov 24 '14 at 02:47
  • 6
    I wrote a performance test for internal evaluation. It had 2000 entries in an ng repeat and displayed 2 attributes in the object, so 2000x2 bindings. The bindings differ in: First binding was just the binding in a span. The seconds had a binding and some plain html in it. The result: ng-bind was faster about 20% per scope apply. Without checking the code, it seems, that additional plain html with a curly expression in a html element takes even more time. – Konstantin Krass Nov 24 '14 at 10:51
  • Angular 1.3.x has a bind once syntax ({{::variable}}). So you can use this to remind the dirty checking and use ng-cloak – TrazeK Nov 26 '14 at 00:45
  • @TrazeK Yeah as misaizdaleka said in the comments. – Konstantin Krass Nov 28 '14 at 12:40
  • 2
    Just want to point out that according to the tests here: http://jsperf.com/angular-bind-vs-brackets seem to show that brackets are FASTER than bind. (Note: bars are ops per second, thus longer is better). And as previous comments point out, their watching mechanisms are ultimately identical. – Warren Dec 09 '14 at 12:42
  • @Warren Your jsPref does measure the bootstrapping time of the test. Because directives have a bigger load, these do have a slower instantiate time. The more important value is the performance taken while running the application. jsPerf does give me 5 different results for 5 executions, so that's why i dont rely on it. – Konstantin Krass Dec 12 '14 at 08:39
  • Are there any performance tests on "bind-once + brackets" vs. "bind-once + ng-bind"? Does the performance hit get eliminated or diminished in this case? – trysis Mar 27 '15 at 20:19
  • Simply ng-repeat 10000 items and ng-bind those. Start profiling with chrome and compare with bind-once. But sorry for spoiling, bind-once will be faster in any case, because there wont be a watcher in the digest loop for that binding (after it got bound) – Konstantin Krass Mar 30 '15 at 07:26
  • I know, I was asking for performance tests on "bind-once + brackets" vs "bind-once + ng-bind". Obviously bind-once will be faster than not-bind-once in most cases. – trysis Mar 30 '15 at 12:27
  • ng-bind needs to "dirty-check" in each digest exactly the same as {{}} does. Also the argument about visible unevaluated expression only applies in some cases. For example inside an ng-repeat you can use {{}} without it ever being visible (because it will only be visible at all, if there already is data). – eekboom Aug 17 '15 at 15:02
  • 1
    Because you'r not providing any source, i give you one: http://ng-perf.com/2014/10/30/tip-4-ng-bind-is-faster-than-expression-bind-and-one-time-bind/ "ng-bind is faster because it’s simpler. interpolation has to go through extra steps of verifying context, jsonification of values and more. that makes it slightly slower." – Konstantin Krass Aug 18 '15 at 07:23
  • 1
    I cannot stand seeing the brackets upon refresh - I'm talking about a small asp.net mvc site with even a page with just 2 {{ templates }} , and I'm talking about angular 1.5.6 which is current . So for me, I'm glad to have stumbled across this page . I loved the years of {{ blah }} but it is not worth the temporary seeing of those brackets and I don't want to use cloak. so for me ng-bind directive it is –  Jun 07 '16 at 07:16
324

If you are not using ng-bind, instead something like this:

<div>
  Hello, {{user.name}}
</div>

you might see the actual Hello, {{user.name}} for a second before user.name is resolved (before the data is loaded)

You could do something like this

<div>
  Hello, <span ng-bind="user.name"></span>
</div>

if that's an issue for you.

Another solution is to use ng-cloak.

serv-inc
  • 35,772
  • 9
  • 166
  • 188
holographic-principle
  • 19,688
  • 10
  • 46
  • 62
  • 4
    Based on what you are saying, there no performance hit if we use {{}}? I was told, if you use {{}}, everytime, that will get inerpolate and generate the result even if the model does not change. – Nair Apr 20 '13 at 23:53
  • So, ng-bind seems to perform better, but I am unsure of just how big of a difference it really makes. My impression is that it won't make a noticable difference unless you are working with really large data sets. Otherwise, I wouldn't worry about that aspect of it. – holographic-principle Apr 20 '13 at 23:57
  • 4
    And how to use ng-bind if I don't want to wrap user.name inside span tag? If I uset curly brackets I'll get clean name, without html tags – Victor Nov 30 '13 at 12:51
  • Hi @finishingmove. could you please explain why using the brackets could result in showing up as `{{something}}` before rendering `$scope.something`? Is it a **bug**? – Kevin Meredith Jan 05 '14 at 01:50
  • 5
    @KevinMeredith it appears like that when the HTML has loaded, but angular has not (yet). Remember that it's client-side templating we're talking about. All the interpolation has to be done in the browser loading the app. Usually angular loads fast enough for it not to be noticeable, but in some cases it becomes a problem. So, `ng-cloak` was invented to mend this problem. – holographic-principle Jan 05 '14 at 10:45
  • 19
    for me, this is not the answer to the question, why ngBind is better. It's just how to use ngBind instead of the {{}} annotation and a reference to ngCloak. – Konstantin Krass Sep 15 '14 at 06:28
  • 4
    @Victor there is also `ng-bind-template` where you can combine both approaches: `ng-bind-template="Hello, {{user.name}}"` Here the binding still offers the performance boost and does not introduce any further nesting – loother Mar 04 '15 at 09:21
  • 2
    Super late in the game here, but the question was about performance advantages of the ngBind directive, which this answer doesn't address. – Shawn Erquhart Mar 13 '15 at 14:43
  • No performance hit AFAIK. The expression gets built and added to to $scope.$$watchers array just the same either way. – superluminary Jan 14 '16 at 14:01
29

ng-bind is better than {{...}}

For example, you could do:

<div>
  Hello, {{variable}}
</div>

This means that the whole text Hello, {{variable}} enclosed by <div> will be copied and stored in memory.

If instead you do something like this:

<div>
  Hello, <span ng-bind="variable"></span>
</div>

Only the value of the value will be stored in memory, and angular will register a watcher (watch expression) which consists of the variable only.

Nico
  • 790
  • 1
  • 8
  • 20
J brian
  • 327
  • 4
  • 6
  • 7
    On the other hand, your DOM is deeper. Depending on what you're doing, in big documents this could impact rendering performance. – stephband Apr 29 '14 at 01:22
  • 2
    Yeah, I think the same way @stephband does. If you just want to display name and last name, for example. Why not just interpolation? It will perform the same way because it will run the same watches in 1 digest. Like:
    {{firstName}} {{lastName}}
    ==
    .. And the first one looks better. I think it depends a lot on what you want but in the end they both have advantages and disadvantages.
    – pgarciacamou May 10 '14 at 00:21
  • 3
    `
    ` is an alternative to {{ }} and functions like ng-bind
    – northamerican Aug 05 '15 at 00:49
  • 1
    This is not apples to apples—you're introducing a span element in one, and not the other. The example with `ng-bind` would be more comparable to `
    Hello, {{variable}}
    `.
    – iconoclast Apr 13 '16 at 18:55
15

Basically the double-curly syntax is more naturally readable and requires less typing.

Both cases produce the same output but.. if you choose to go with {{}} there is a chance that the user will see for some milliseconds the {{}} before your template is rendered by angular. So if you notice any {{}} then is better to use ng-bind.

Also very important is that only in your index.html of your angular app you can have un-rendered {{}}. If you are using directives so then templates, there is no chance to see that because angular first render the template and after append it to the DOM.

Drewness
  • 5,004
  • 4
  • 32
  • 50
hellopath
  • 223
  • 1
  • 6
  • 5
    Interestingly enough, it's not the same. I get no output on ng-bind="anArrayViaFactory" vs {{anArrayViaFactory}}. I came across this issue when trying to output a json response in a jekyll protoype but because of a conflict with similar templating {{}}, I was forced to used ng-bind. An ng-bind inside an ng-repeat block (item in anArrayViaFactory) will output values. – eddywashere Jan 21 '14 at 23:16
5

{{...}} is meant two-way data binding. But, ng-bind is actually meant for one-way data binding.

Using ng-bind will reduce the number of watchers in your page. Hence ng-bind will be faster than {{...}}. So, if you only want to display a value and its updates, and do not want to reflect its change from UI back to the controller, then go for ng-bind. This will increase the page performance and reduce the page load time.

<div>
  Hello, <span ng-bind="variable"></span>
</div>
Drewness
  • 5,004
  • 4
  • 32
  • 50
Tessy Thomas
  • 1,475
  • 12
  • 19
4

This is because with {{}} the angular compiler considers both the text node and it's parent as there is a possibility of merging of 2 {{}} nodes. Hence there are additional linkers that add to the load time. Of course for a few such occurrences the difference is immaterial, however when you are using this inside a repeater of large number of items, it will cause an impact in slower runtime environment.

Drewness
  • 5,004
  • 4
  • 32
  • 50
Ambika Sukla
  • 244
  • 4
  • 3
3

enter image description here

The reason why Ng-Bind is better because,

When Your page is not Loaded or when your internet is slow or when your website loaded half, then you can see these type of issues (Check the Screen Shot with Read mark) will be triggered on Screen which is Completly weird. To avoid such we should use Ng-bind

Community
  • 1
  • 1
Vikas Kalapur
  • 415
  • 4
  • 12
1

ng-bind has its problems too.When you try to use angular filters, limit or something else, you maybe can have problem if you use ng-bind. But in other case, ng-bind is better in UX side.when user opens a page, he/she will see (10ms-100ms) that print symbols ( {{ ... }} ), that's why ng-bind is better.

Hazarapet Tunanyan
  • 2,809
  • 26
  • 30
1

There is some flickering problem in {{ }} like when you refresh the page then for a short spam of time expression is seen.So we should use ng-bind instead of expression for data depiction.

GAURAV ROY
  • 1,885
  • 1
  • 12
  • 4
0

ng-bind is also safer because it represents html as a string.

So for example, '<script on*=maliciousCode()></script>' will be displayed as a string and not be executed.

raneshu
  • 363
  • 2
  • 16
  • 46
0

According to Angular Doc:
Since ngBind is an element attribute, it makes the bindings invisible to the user while the page is loading... it's the main difference...

Basically until every dom elements not loaded, we can not see them and because ngBind is attribute on the element, it waits until the doms come into play... more info below

ngBind
- directive in module ng

The ngBind attribute tells AngularJS to replace the text content of the specified HTML element with the value of a given expression, and to update the text content when the value of that expression changes.

Typically, you don't use ngBind directly, but instead you use the double curly markup like {{ expression }} which is similar but less verbose.

It is preferable to use ngBind instead of {{ expression }} if a template is momentarily displayed by the browser in its raw state before AngularJS compiles it. Since ngBind is an element attribute, it makes the bindings invisible to the user while the page is loading.

An alternative solution to this problem would be using the ngCloak directive. visit here

for more info about the ngbind visit this page: https://docs.angularjs.org/api/ng/directive/ngBind

You could do something like this as attribute, ng-bind:

<div ng-bind="my.name"></div>

or do interpolation as below:

<div>{{my.name}}</div>

or this way with ng-cloak attributes in AngularJs:

<div id="my-name" ng-cloak>{{my.name}}</div>

ng-cloak avoid flashing on the dom and wait until all be ready! this is equal to ng-bind attribute...

Alireza
  • 100,211
  • 27
  • 269
  • 172
0

You can refer to this site it will give you a explanation which one is better as i know {{}} this is slower than ng-bind.

http://corpus.hubwiz.com/2/angularjs/16125872.html refer this site.

Sneha
  • 153
  • 1
  • 1
  • 10