kseamon / fast-bind

Alternatives to AngularJS's built-in bindings that avoid taxing the digest cycle
MIT License
83 stars 10 forks source link

ng-repeat performance #1

Open colinskow opened 10 years ago

colinskow commented 10 years ago

Thanks for sharing Karl.

I'd love to see fast-bind-once and fast-bind-on-notify become a standard part of AngularJS!!!

Have you tested fast-bind-on-notify on large ng-repeats? From what I understand ng-repeat applies a $watchCollection to the entire dataset, so it may be dirty checking everything, even if I use only fast-bind-on-notify within the repeat.

Would it be necessary to re-write ng-repeat to really get the performance benefits?

Please see my question on Github and feel free to add an answer. Your solution is the best I've seen so far.

http://stackoverflow.com/questions/20542521/prevent-angularjs-from-dirty-checking-several-thousand-rows-each-digest-cycle

Thanks,

kseamon commented 10 years ago

ng-repeat's $watchCollection will do one one referential check per iteration per digest cycle (One watcher, numerous comparisons).

Any bindings inside of it will additionally do dirty checks on each digest cycle.

So if items.length is 100:

<div ng-repeat="item in items"></div> -> 1 binding, 100 comparisons
<div ng-repeat="item in items" ng-bind="item.name"></div> -> 101 binding, 200 comparisons
<div ng-repeat="item in items" ng-bind="item.name" ng-class="item.class"></div> -> 201 binding, 300 comparisons

etc.

fast-bind-on-notify (and a hypothetical fast-class-on-notify) would not cut down on ng-repeat's own checks, but they'd substantially help with all of the other ones.

I suppose one could also make a fast-repeat-on-notify that only updates its bindings based on another watcher, or a version of repeat that uses a shallow $watch rather than $watchCollection, but it would be a lot of lines of code for potentially not a huge payoff.

colinskow commented 10 years ago

Thanks. I'm working on a CRM app and I want customers to be able to scroll through potentially several thousand records without lag. PouchDB automatically syncs my data to the server and fires a callback on every change.

With small amounts of data it doesn't matter, but it would be nice if Angular gave more control over $scope.apply, specifically enabling us to isolate sections of scope from the normal $digest cycle so we can call it manually.

I'll try with and without fast-bind-on-notify, and if performance is still a problem I'll ask for help in tweaking ng-repeat. It wouldn't require a lot of code. We could probably just change the $scope.$watchCollection to a $scope.$on. (ngrepeat.js line 256)