Reputation: 4001
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 :)
Upvotes: 2
Views: 2230
Reputation: 1061
$destroy
events to clean up event watchersng-repeat
, ng-options
)$digest
(ng-if="ctrl.isDataLiading()"
slower then ng-if="ctrl.isDataLoaded"
)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 itemsWhen 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
Upvotes: 4