I have an AngularJS app with a paged grid (two nested ng-repeat). One page has approximately 25x40 input elements. In the beginning that made 1000 bindings, the paging performance was acceptable.
But then the complexity of page grow: dynamic classes, varying context menues, conditional content for each cell of the grid. And with estimated 6000 bindings (6 per input element) the paging got unusable slow.
My question is: how do I generally approach performance problems in AngularJS? The obvious first step ist to measure. But the results of the Chrome Profiler do not tell me that much, far from knowing how to proceed.
Self Total Function ----------------------------------------------------------------- 24 ms 2.79 s angular.js:7997 Scope.$digest 1 ms 1 ms controllers.js:365 setViewportData 16 ms 692 ms angular.js:13968 ngRepeatWatch 8 ms 22 ms angular.js:6439 extend.literal 9 ms 1.22 s angular.js:14268 ngSwitchWatchAction 16 ms 45 ms angular.js:12436 ngModelWatch 0 621 ms angular-ui-4.0.js:264 initDateWidget 0 13 ms angular.js:12859 ngClassWatchAction 0 70 ms angular.js:14184 ngStyleWatchAction 1 ms 5 ms angular-ui-4.0.js:261 getOptions 0 16 ms angular.js:579 copy 0 1 ms angular.js:4558 interpolateFnWatchAction 1 ms 2 ms angular.js:5981 token.fn.extend.assign 0 37 ms angular.js:8151 Scope.$eval 1 ms 1 ms angular.js:6137 extend.constant 14 ms 16 ms angular.js:651 equals 1 ms 1 ms angular.js:4939 $interpolate.fn
Aside: is there any chance that 'Object.observe()' will speed up things in the future (ignoring 'initDateWidget', that's obviously a different topic)?
Usually, if your app is becoming slow, the main reason for it is too many watchers. AngularJS uses dirty checking to keep track of all the changes made in the code. If two watchers are interlinked, the digest cycle runs twice to ensure that all the data is updated.
Angular is not generating HTML and then passing it to the browser to have it parsed, instead Angular is generating DOM data structures directly! This works much faster than building manually HTML and then passing it to the DOM for parsing.
As Angular is based on JavaScript, it is faster and easier to learn AngularJS. It supports faster prototyping and coding, which lowers development time. Two-way data binding of AngularJS helps in more accessible and faster data binding with no interference of the developers.
If you've done your research and figured out that your app doesn't render that much and doesn't render that often, then your code may just simply be quite slow. This is probably due to some heavy scripting and not DOM-related. Use WebWorkers. The Angular CLI also provides a command to generate a WebWorker in a snap.
The thing you can do that will speed up your Angular app the most is to reduce those bindings where you can. One way to do this would be to create a directive that built out the table for you with DOM manipulation rather than using ng-repeats. This will reduce the number of overall watches you have to process, and make that $digest a lot faster.
I know it's ugly to do that, but Angular's not really meant to set up 3000+ bindings. Since it does a digest and it's not an observer pattern, it really slows things down have that many set up.
You could even do a hybrid approach, where you still used the ng-repeat, but all of the values were placed in the DOM with straight DOM manipulation from a custom directive, thus avoiding all of the bindings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With