Performance when loading data with a lot of bindings using ng-repeat

298 views
Skip to first unread message

AndrewM

unread,
Mar 6, 2013, 11:55:53 PM3/6/13
to ang...@googlegroups.com
Hi all, I am running into performance problems building a conversation system with nested comments using angularjs.
 
Each comment has ~40 bindings and this causes a lot of slowness when loading even moderate length threads. Loading a comment thread with ~30 comments will freeze the page for several seconds while compiling the 40 bindings * 30 posts = 1200 total bindings in the comments thread. On top of this if enough bindings (> 3000) are loaded then the page becomes very slow for the user as each digest cycle takes a very long time.
 
I have tried reducing the number of bindings that each comment uses but ~40 is pretty much a minimum for the information and controls that I want to display with each comment. I could paginate the comments but having paging with < 30 comments per page would be annoying for users and I would rather be able to display a comment thread of any length without pagination.
 
with an ng-repeat of 10 bindings per row * 91 rows = 910 bindings to compile and place on the page.
 
I have considered two solutions:
  1. Write a directive to "detach" my expensive scopes from the scope hierarchy and manually digest them when needed. This is not optimal obviously because then I lose some of the "magic" of angular by being forced to manually digest some of my scopes. I also don't think this would help with the "page freezes for 2 seconds" due to loading lots of bindings all at once in an ng-repeat.
  2. Write a directive that guesses the height of my content and only compiles those comments which are in the user's viewport. This option might work better than the first, but would be very complicated.
 
How can I work around this performance issue of having an arbitrary number of fairly complex "widgets" repeated onto the page?
 
Thanks!

Saurabh Nanda

unread,
Mar 7, 2013, 3:38:20 AM3/7/13
to ang...@googlegroups.com
Do you really need 40 *two-way data-bindings* per-comment? Once a comment has been rendered on to the page, does a user interaction really change any of those 40 data-bindings?

Saurabh.

AndrewM

unread,
Mar 7, 2013, 9:22:59 AM3/7/13
to ang...@googlegroups.com
Sorry I don't think I was clear with what I meant by bindings. I added a bit of code to angular's digest function to count the number of watches being run and what I meant by "40 bindings" is that each of my comments has about 40 watches being run on it per digest cycle.
 
The way I have designed my system allows for a lot of user interaction -- the user can vote on comments, give points to other users for helpful comments, save comments, report them, reply to them, view a summary of voting data, and a few other things. On top of this all of my data is updated in real time from my server through pubnub. This is why I say that ~40 watches per comment is about the minimum I can make it to support all the features I want for my users. 
 
Even if I were able to bring that number much lower (say ~10) I don't think that would solve my problem becuase even then loading a thread of 120 comments which is long but not impossible would have the same slowness of 1200 watches as my example above.
 
While I might be able to further optimize my application I am still interested in how I might work through the situation of loading an arbitrarily long set of widgets with ng-repeat. Is my solution above of writing a directive to only compile those that are in the user's viewport a good idea?

Saurabh Nanda

unread,
Mar 7, 2013, 9:35:34 AM3/7/13
to ang...@googlegroups.com
Two possible solutions that I can think of [1]:

(a) Make a comment directive with each comment having a separate scope. Any DOM event within that directly should call scope.$digest instead of scope.$apply to not trigger an app-wide digest cycle, but only a "local" digest cycle. 

(b) Make a commentList directive which adds watches/bindings for only those comments that are visible. It should bind to the paginations controls or the container's scroll event and remove/add bindings for comments that move out/int of the viewport respectively.

[1] I'm just taking a shot at this and am not 100% sure if these will work.

Saurabh.

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/bTPDKecL2NU/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
http://www.saurabhnanda.com
Message has been deleted
Message has been deleted

redk...@gmail.com

unread,
Jun 17, 2015, 12:31:21 PM6/17/15
to ang...@googlegroups.com
Can you not also handle the data-bindings external to A-JS ? Thus exercise greater control on the granularity at which the events are triggered?

Sander Elias

unread,
Jun 18, 2015, 5:54:49 AM6/18/15
to ang...@googlegroups.com
Hi AndrewM,

You should switch over to version 1.4, which is the fastest Angular yet. Then make use of one-time bindings for most of your bindings. My bet is that you can get rid of 80% of your bindings this way. Probably enough to get rid of your page freezes.

Regards
Sander

Reply all
Reply to author
Forward
0 new messages