30

I have read some articles that said ng-repeat would led to poor performance if there is over 2000 items, because there are too many two way binding to watch. I am new to angularjs and have trouble understanding the relationship between ng-repeat and two-way binding:

  1. Does ng-repeat (like outputting a list of json objects) necessarily create two way binding?

  2. Is there a simple way to do ng-repeat using only one way binding? (preferably do not need external module)

Dionysian
  • 1,195
  • 2
  • 13
  • 24
  • If you have this amount of data, you should consider using a kind of pagination. – Beterraba Nov 05 '13 at 19:34
  • I imagine you would have to write your own custom ng-repeat directive utilizing ng-bind (one way data binding) rather than ng-model (two way data binding). – Zack Argyle Nov 05 '13 at 19:39
  • @Beterraba He just gave a example. what he actually meant is huge size applications which may have more data inside different widgets. – JSAddict Apr 30 '14 at 11:21

4 Answers4

58

Like user1843640 mentioned, if you are on Angular 1.3, you can use one-time-binding, but, just for clarity, you need to put the :: on all the bindings, not just the repeater. The docs say do this:

<div ng-repeat="item in ::items">{{item.name}}</div>

But, if I count the watchers, this only removed one. To really drop the number of two-way-bindings, place the :: on the bindings within the repeater, like this:

<div ng-repeat="item in ::items">{{::item.name}}</div>

Here are two plunkers that will display the number of watchers:

All Bindings
Repeater Only

Thanks goes out to Miraage for provinding the function to count the watchers https://stackoverflow.com/a/23470578/2200446

Community
  • 1
  • 1
Cindy Conway
  • 1,814
  • 3
  • 18
  • 19
  • In my scenario I have 3tabs in a single page.so for the page load it is working since it will load the first tab and when I switch between the 3 tabs, it is not triggering since it is a single binding. can you provide some guidance for this scenario. 2 way binding taking time while switching between the tabs. – Raphael Feb 07 '19 at 14:53
17

For anyone using or upgrading to Angular 1.3 you can now use "one-time binding". For ng-repeat it would look like this:

<div ng-repeat="item in ::items">{{item.name}}</div>

Notice the ::items syntax.

For more information check the Angular documentation for expressions.

user1843640
  • 3,613
  • 3
  • 31
  • 44
3

This blog post presents some interesting solutions. The end result was:

Upgrade to AngularJS 1.1.5 and use limitTo together with Infinite scrolling. AngularJS ng-repeat offers from version 1.1.4 the limitTo option. I slightly adapted the Infinite Scroll directive to make scrolling within a container possible that does not have height 100% of window.

Basically you limit the number of objects you initially render, then use the Infinite scrolling directive to render more as needed. Since you don't want an external module, just mimic the infinite scroll functionality as needed with your own script.

Note: This should solve your performance problem but it won't remove two-way binding.

hiattp
  • 2,326
  • 1
  • 20
  • 23
2
  1. what ever is generated by ng-model will be having a watcher on data(model) which reduces the page performance if it crosses 200 watchers.

  2. Refer this for ONE WAY BINDING http://blog.scalyr.com/2013/10/31/angularjs-1200ms-to-35ms/ but make sure you use it properly

Hope it helps!!!

JSAddict
  • 12,407
  • 7
  • 29
  • 49