alexkras.com

  • Home
  • Top Posts
  • Resume
  • Projects
  • YouTube
  • Boots to Bytes
  • About
  • Contact

11 Tips to Improve AngularJS Performance

April 28, 2015 by Alex Kras 64 Comments

I am new to Angular (even though I am not new to the web development), so please take everything that I am about to say with a grain of salt. That being said, I watched a lot of talks and read a lot of articles relevant to Angular performance, and this post is the summary of my findings.

Please make sure to check out some other posts: My Interview at Uber, 19 Tips For Everyday Git Use, Simple Guide to Finding a JavaScript Memory Leak in Node.js and I Tried To Virtually Stalk Mark Zuckerberg.

Table of Contents

  1. Minimize/Avoid Watchers
  2. Avoid ng-repeat. If you have to use ng-repeat use infinite scrolling or pagination
  3. Use Bind once when possible
  4. Use $watchCollection instead of $watch (with a 3rd parameter)
  5. Avoid repeated filters and cache data whenever possible
  6. Debounce ng-model
  7. Use ng-if instead of ng-show (but confirm that ng-if is actually better for your case
  8. Use console.time to benchmark your functions
  9. Use native JavaScript or Lodash for slow functions
  10. Use Batarang to benchmark your watchers
  11. Use Chrome Timeline and Profiler to identify performance bottlenecks

1. Minimize/Avoid Watchers

Usually, if your Angular app is slow, it means that you either have too many watcher, or those watchers are working harder then they should.

Angular uses dirty checking to keep track of all the changes in app. This means it will have to go through every watcher to check if they need to be updated (call the digest cycle). If one of the watcher is relied upon by another watcher, Angular would have to re-run the digest cycle again, to make sure that all of the changes has propagated. It will continue to do so, until all of the watchers have been updated and app has stabilized.

Even though running JavaScript in modern browsers is really fast, in Angular it is fairly easy to add so many watchers that you app will slow down to a crawl.

Keep in mind the following when implementing or refactoring an Angular app.
http://www.codelord.net/2014/06/17/angular-performance-101-slides/

  1. Watches are set on:
    • $scope.$watch
    • {{ }} type bindings
    • Most directives (i.e. ng-show)
    • Scope variables scope: { bar: '='}
    • Filters {{ value | myFilter }}
    • ng-repeat
  2. Watchers (digest cycle) run on
    • User action (ng-click etc). Most built in directives will call $scope.apply upon completion which triggers the digest cycle.
    • ng-change
    • ng-model
    • $http events (so all ajax calls)
    • $q promises resolved
    • $timeout
    • $interval
    • Manual call to $scope.apply and $scope.digest

2. Avoid ng-repeat. If you have to use ng-repeat use infinite scrolling or pagination

This was the biggest win for our app. I am not going to go into too much details, but I found the article bellow to be extremely helpful.

http://www.williambrownstreet.net/blog/2013/07/angularjs-my-solution-to-the-ng-repeat-performance-problem/

In addition to infinite scroll, make sure to use track by when possible. https://docs.angularjs.org/api/ng/directive/ngRepeat#tracking-and-duplicates

For example a unique step id, is a good value to track by when doing an ng-repeat.

<li ng-repeat="Task in Tasks track by Task.Id></li>

3. Use Bind once when possible

Angular 1.3 added :: notation to allow one time binding. In summary, Angular will wait for a value to stabilize after it’s first series of digest cycles, and will use that value to render the DOM element. After that, Angular will remove the watcher forgetting about that binding.
https://code.angularjs.org/1.3.15/docs/guide/expression#one-time-binding

See the Pen AngularJS – Bind Once Example by Alex (@akras14) on CodePen.

If you are on pre 1.3 version of Angular you can use this library to achieve similar results:
https://github.com/Pasvaz/bindonce

4. Use $watchCollection instead of $watch (with a 3rd parameter)

$watch with only 2 parameters, is fast. However, Angular supports a 3rd parameter to this function, that can look like this: $watch('value', function(){}, true). The third parameter, tells Angular to perform deep checking, meaning to check every property of the object, which could be very expensive.

To address this performance issue, angular added $watchCollection('value', function(){}). $watchColleciton acts almost like $watch with a 3rd parameter, except it only checks the first layer of object’s properties, thus greatly improving the performance.

Official doc:
https://code.angularjs.org/1.3.15/docs/api/ng/type/$rootScope.Scope#$watchCollection

Helpful blog post:
http://www.bennadel.com/blog/2566-scope-watch-vs-watchcollection-in-angularjs.htm

5. Avoid repeated filters and cache data whenever possible

One time binding does not seem to play well with filters. There seems to be work arounds to make it work, but I think it’s cleaner and more intuitive to simply assign the needed value to a variable (or set it as a property on an object, if you are dealing with a lot of variables).

For example, instead of:

{{'DESCRIPTION' | translate }}

You can do:
– In JavaScript $scope.description: $translate.instant('DESCRIPTION')
– In HTML {{::description}}

Or instead of: {{step.time_modified | timeFormatFilter}}

  • In JavaScript
var timeFormatFilter = $filter('timeFormatFilter');
step.time_modified = timeFormatFilter(step.time_modified);
  • In HTML {{::Path.time_modified}}

6. Debounce ng-model

If you know there is going to be a lot of changes coming from an ng-model, you can de-bounce the input.

For example if you have a search input like Google, you can de-bounce it by setting the following ng-model option: ng-model-options="{ debounce: 250 }.

This will ensure that the digest cycle due to the changes in this input model will get triggered no more then once per 250ms .

https://docs.angularjs.org/api/ng/directive/ngModelOptions

7. Use ng-if instead of ng-show (but confirm that ng-if is actually better for your use case)

ng-show will render an element, and use display:none to hide it,
ng-if will actually removes the element from DOM, and will re-create it, if it’s needed.

You may need ng-show for an elements that toggles on an off often, but for 95% of the time, ng-if is a better way to go.

8. Use console.time to benchmark your functions

console.time is a great API, and I found it particularly helpful when debugging issues with Angular performance. I placed a number of those calls through out my code, to help me confirm that my re-factoring was in fact improving the performance.

https://developer.mozilla.org/en-US/docs/Web/API/Console/time

The API looks as such:

console.time("TimerName");
//Some code
console.timeEnd("TimerName");

And here is a simple example:

console.time("TimerName");
setTimeout(function(){
    console.timeEnd("TimerName");
}, 100);
//In console $: TimerName: 100.324ms

Note: If console.time is not precise enough for your needs, you can get a more accurate reading using performance.now(). You will have to do your own math, if you choose to take this path.

https://docs.google.com/presentation/…

totalTime = 0; count = 0;
var someFunction = function() {
  var thisRunStartTime = performance.now();
  count++;
  // some code

  // some more code
  totalTime += performance.now() - thisRunStartTime;
};
console.log("Average time: " + totalTime/count);

9. Use native JavaScript or Lodash for slow functions

Our app was already using lodash, so there was no overhead for me to use it in my optimization. If lodash was not include, I would probably try to re-write everything in native JavaScript.

In my tests I got a significant performance boost by simply re-writing some of the basic logic with lodash, instead of relying on built-in Angular methods (which have to account for much more generic use cases).

Maintainer of Lodash John-David Dalton is also a co-creator of https://jsperf.com/, and he is all about the performance. So I trust him and his library when it comes to speed.

10. Use Batarang to benchmark your watchers

Batarang is a great tool from the Angular team, and it was very helpful in my debugging efforts. It has a lot of useful features, but the one that was the most relevant to this use-case is the performance tab.

batarang

Make sure to get the stable version, which seems to work for the majority of users.
https://chrome.google.com/webstore/detail/angularjs-batarang-stable/niopocochgahfkiccpjmmpchncjoapek

Watch this video to get more insight into the Batarang.

11. Use Chrome Timeline and Profiler to identify performance bottlenecks

I like to think of myself as a Chrome Dev Tools power user. But it’s not often that I get a to use the Timeline and Profiler views. In this project, both were extremely helpful.

Pro Tip: If you use console.time API (see tip #8), the time period will get highlighted on your timeline snapshot. So you can examine the exact time period that you care about the most.

https://developer.chrome.com/devtools/docs/timeline#user-produced-timeline-events

The timeline view, and the magic 60fps line is crucial. When I started on our project, the app was rendering full steam for 15 seconds or more, becoming almost completely unresponsive to the user.

Old

After performance optimization, the app now fully renders in less then 2 seconds (note that the time scale is different), allowing users to freely interact with the user interface after a relatively short delay.

New

It is clear from looking at the image that the app could be further optimized. But even as is, I am very happy with the improvements to the user experience.

To get more experience with Timeline view, check out these web audits by Paul Irish:

https://docs.google.com/document/d/1K-mKOqiUiSjgZTEscBLjtjd6E67oiK8H2ztOiq5tigk/pub

Finally, I wanted to mentioned the Profiling tab in Chrome Dev tools, and the JavaScript CPU profiler in particular. It has 3 views:

1. Chart view is similar to the timeline, but it makes it a bit easier to jump to the source code of the function of interest.

chart

2. Heavy (Bottom up view)
This view identifies heavy user functions, and shows you the reverse call stack to help pinpoint origination of the function. Note how $digest comes before the $apply, indicating the reverse order.

Heavy-bottom-up

3. Tree (Top Down)
Exposes the functions from which the heavy consumption originated, and then you can drill down to find the offending function.

Also note the yellow triangle with a “!”, if you however over it, it will identify a potential optimization problem.

top-down

https://developer.chrome.com/devtools/docs/cpu-profiling

P.S. If you found these tips helpful, please consider reviewing this post on Amazon

Filed Under: Front End

I work for Evernote and we are hiring!

Subscribe to this Blog via Email

New posts only. No other messages will be sent.

You can find me on LinkedIn, GitHub, Twitter or Facebook.

This blog is moving to techtldr.com

Comments

    Leave a Reply Cancel reply

  1. Bhuvana Kandhan says

    October 16, 2018 at 11:21 pm

    Expected to form you a next to no word to thank you once more with respect to the decent recommendations you’ve contributed here. We are providing AngularJs training in velachery.
    For more details: AngularJs training in velachery

    Reply
  2. Bren says

    March 24, 2017 at 4:58 am

    Hrmm:
    https://www.linkedin.com/pulse/11-tips-improve-angularjs-performance-shaik-ui

    Reply
  3. Mujamil says

    March 6, 2017 at 5:05 am

    Useful Alex!

    Reply
  4. MoorthiMoorthi says

    February 21, 2017 at 6:59 pm

    Great article !! loved it

    Reply
  5. George Mason says

    December 21, 2016 at 10:37 pm

    great post. I would also recommend checking out this on stackchief.com great article about watchers and the effects they have on performance.
    https://www.stackchief.com/blog/Understanding%20Watchers%20in%20AngularJS

    Reply
  6. Siddharth Sharma says

    November 20, 2016 at 2:17 am

    Not since angular2 is production ready, there is an option to migrate your current application to angular2 module by module, here is link to an article showing performance difference between angular1 and angular2.
    https://medium.com/@hearsid/performance-comparison-of-angularjs-1-x-and-angularjs-2-through-contacts-manger-application-ccb5f00f29b1#.ujnqme4zw

    Reply
  7. haha says

    October 17, 2016 at 11:42 am

    what about angular 2 ?

    Reply
    • Siddharth Sharma says

      November 20, 2016 at 2:15 am

      Angular2 is much more flexible in making changes to enhance performance, here is an article about angular1 vs angular2 performance which you may find interesting.
      https://medium.com/@hearsid/performance-comparison-of-angularjs-1-x-and-angularjs-2-through-contacts-manger-application-ccb5f00f29b1#.ujnqme4zw
      I’m wrote the article by the way.

      Reply
  8. Ozgur says

    May 23, 2016 at 3:56 pm

    ‘track by’ in ngRepeat was extremely, very extremely useful for me. Thank you so much.

    Reply
  9. Scott Kamps-Duac says

    May 4, 2016 at 9:44 am

    Don’t forget about Disabling Debug Data! https://docs.angularjs.org/guide/production

    Reply
  10. 1antares1 says

    March 12, 2016 at 9:34 pm

    Impressive collection, useful and tidy. I take it. Thank you for sharing your valuable time.

    Reply
  11. Rajive says

    February 25, 2016 at 8:25 pm

    Useful Alex!

    Reply
  12. DH says

    January 27, 2016 at 4:36 pm

    Number 7 simply can’t be right??? Messing with the DOM is always one of the most expensive actions of all?

    Reply
    • Jonatas says

      March 15, 2016 at 12:27 pm

      ng-if doesn’t parse html based on condition, so no watchers will be applied to the piece of html removed by ng-if. So ng-if ends up cheaper than ng-hide/ng-show

      Reply
  13. Linh Le says

    January 26, 2016 at 3:22 am

    Useful article. Thanks.

    Reply
  14. Gaurav says

    January 7, 2016 at 6:57 am

    Good

    Reply
  15. nayef says

    December 9, 2015 at 8:35 am

    V.good articel and helpfull.

    Thx

    Reply
  16. Pradheep says

    November 5, 2015 at 10:40 am

    Excellent article. I have a query on the lodash performance when compared to native for loop.
    https://github.com/angular/angular.js/issues/12628
    Native for forward loop is very fast when compared to lodash and angular js. So, is it a good option to always prefer native for or should we depend on the libraries.

    Reply
  17. Alouise Quiatchon says

    October 7, 2015 at 6:24 pm

    Awesome article and very helpful! Keep posting!

    Reply
    • Alex Kras says

      April 8, 2016 at 1:51 am

      Haha, thanks man. Just noticed it 🙂

      Reply
  18. Gleb Bahmutov says

    October 1, 2015 at 4:11 pm

    Good list, I can recommend using my collection of Chrome code snippets to debug angular performance problems. For example you can get the number of watchers, or time / profile digest cycle or an individual method. https://github.com/bahmutov/code-snippets

    See example application steps in http://glebbahmutov.com/blog/improving-angular-web-app-performance-example/

    Reply
  19. Swanidhi says

    September 23, 2015 at 12:42 pm

    Outstanding! This is the single most comprehensive article for all AngularJS performance concerns. This should be on github. Bookmarked though!
    Thanks!

    Reply
  20. Huy Minh says

    September 8, 2015 at 3:11 am

    Excellent article!

    Reply
  21. aslam says

    September 3, 2015 at 6:20 am

    this is super helpful!

    Reply
  22. BestDesignHelp says

    August 30, 2015 at 7:56 am

    Great collection! Well done 😉

    Reply
  23. Nyein Aung says

    August 11, 2015 at 8:44 am

    Very Useful

    Reply
  24. Pawel says

    July 16, 2015 at 10:01 am

    Great article, thank you very much!

    Reply
  25. Dhivya says

    June 30, 2015 at 8:53 am

    Excellent article…

    Reply
  26. Alireza says

    May 27, 2015 at 6:12 pm

    Great post! very useful for me. Thank you very much.

    Reply
  27. OlgaGr says

    May 24, 2015 at 4:05 am

    Maybe in the past Batarang was valuable tool, but right now it is useless. It has only two options: scopes and hints and it shows nothing that can help you.

    Reply
    • David Colwell says

      July 21, 2015 at 8:53 pm

      Don’t use the most cutting edge version of batarang…you are right, that version is useless!
      Use this slightly older and more stable version – which still works wonderfully (my team uses it constantly!) and gives you all the features you are used to.

      https://chrome.google.com/webstore/detail/angularjs-batarang-stable/niopocochgahfkiccpjmmpchncjoapek?hl=en-US

      Reply
  28. Offirmo says

    May 1, 2015 at 2:17 pm

    Hello,

    I just found yesterday a less known easy way to speed up angular : turn off angular’s debug features !

    Angular manages debug infos by default, and switching to production mode is supposed to provide a « significative performance boost » according to the official doc : https://docs.angularjs.org/guide/production

    Reply
    • YoungDev says

      June 1, 2016 at 3:20 pm

      I love you man! That just made my life full of unicorns and rainbows with the performance boost, thanks a lot for sharing!

      Reply
  29. Anil says

    April 30, 2015 at 4:23 am

    Awesome post!! Its very useful for me!!

    Thank you!
    http://www.code-sample.com/2014/09/angularjs-documentation.html

    Reply
  30. Ravi says

    April 29, 2015 at 5:12 am

    Thanks, Very helpful

    Reply
  31. Pierre Paul Lefebvre says

    April 28, 2015 at 5:29 pm

    Excellent article. Thanks for this!

    Reply
  32. MURALI says

    April 28, 2015 at 11:23 am

    This is an excellent article. Thanks for writing this up.

    Reply

Trackbacks

  1. 5 Day Journey to Improve Performance of your AngularJS application | Andy's Blog says:
    May 12, 2018 at 5:44 pm

    […] 11 tips to Improve AngularJS performance […]

    Reply
  2. 11 Tips to Improve Angular I Performance – Full-Stack Feed says:
    March 24, 2017 at 1:08 am

    […] I am new to Angular (even though I am not new to the web development), so please take everything that I am about to say with a grain of salt. That being said, I watched a lot of talks and read a lo… Read more […]

    Reply
  3. 11 Tips to Improve AngularJS Performance says:
    March 24, 2017 at 12:28 am

    […] I am new to Angular (even though I am not new to the web development), so please take everything that I am about to say with a grain of salt. That being said, I watched a lot of talks and read a lo… – Read full story at Hacker News […]

    Reply
  4. Easy and effective solutions to improve performances issues in AngularJS 1.x | Java and Angular says:
    March 19, 2017 at 10:57 am

    […] A list of performance improvements measures : https://www.alexkras.com/11-tips-to-improve-angularjs-performance/ […]

    Reply
  5. 11 Tips to Improve AngularJS Performance | Performance says:
    January 22, 2017 at 10:48 am

    […] Source: 11 Tips to Improve AngularJS Performance […]

    Reply
  6. Get Angular 1 Features in Angular 2 | Webammer says:
    November 22, 2016 at 9:12 am

    […] Then we either have to use JS to set the DOM property (min-height in this case) or we have to add watchers by binding in the template. None of this is […]

    Reply
  7. Speeding up AngularJS – jasna says:
    October 20, 2016 at 2:41 pm

    […] Alex Kras: 11 tips to improve AngularJS Performance […]

    Reply
  8. Angular Performance – DiscVentionsTech says:
    August 16, 2016 at 11:41 am

    […] https://www.alexkras.com/11-tips-to-improve-angularjs-performance/ […]

    Reply
  9. 11 tips to improve angularjs performance by alexkras.co | hadoopminds says:
    June 16, 2016 at 10:33 am

    […] 11 Tips to Improve AngularJS Performance […]

    Reply
  10. Confluence: Software Development says:
    May 12, 2016 at 5:15 pm

    Angular Performance Optimizations – Lessons Learned

    Overview Angular has two major components – the de

    Reply
  11. Confluence: Sony Playstation says:
    April 28, 2016 at 1:07 pm

    Performance

    Testing Performance and Speed   https://www.airpai

    Reply
  12. Confluence: Frontend says:
    March 23, 2016 at 12:53 pm

    Frontend Wiki

    Dla początkujących Podstawy Popularne narzędzia i

    Reply
  13. Angular Performance Tips - Duncan Leung - Fullstack Javascript Web Developer says:
    February 11, 2016 at 8:46 pm

    […] The eager developer that I am =p, I did more reading and I found this primer on Angular performance: 11 Tips To Improve AngularJS Performance. […]

    Reply
  14. Improve AngularJS performance on multiple levels - HTML CODE says:
    January 17, 2016 at 1:43 am

    […] 11 tips improve angularjs performance […]

    Reply
  15. Qualitätsziele von Angular 2 - Startup- und Tech-Blog says:
    January 13, 2016 at 7:01 pm

    […] prüfen musste, welche Konstrukte man wie und in welchem Kontext einsetzte (siehe Lösungen z.B. hier). Symptome für die Performance-Probleme von AngularJS entdeckt man auch bei einem Konstrukt vom […]

    Reply
  16. Confluence: Curriculum Foundry says:
    October 29, 2015 at 9:12 pm

    Angular Performance Optimizations – Lessons Learned

    Overview We attempted to “Angularize” the large and clumsy Gradebook UI with 2 goals in mind offload all the crazy serverbased HTMLgenerating code, and make the loading of large classes faster….

    Reply
  17. Confluence: Curriculum Foundry says:
    October 29, 2015 at 9:04 pm

    Anguler Performance Optimizations – Lessons Learned

    Overview We attempted to “Angularize” the large and clumsy Gradebook UI with 2 goals in mind offload all the crazy serverbased HTMLgenerating code, and make the loading of large classes faster….

    Reply
  18. Confluence: Intercompany says:
    October 29, 2015 at 8:08 am

    Guideline for Front-end development

    AngularJS Style Guide https://github.com/johnpapa/

    Reply
  19. What to Expect and How to Prepare for Your Angular.js Interview: Part 1 says:
    October 27, 2015 at 8:38 pm

    […] For more tips on how to improve Angular JS performance, check out this site. […]

    Reply
  20. Daily links 2015-10-20 | Marcin Kossowski says:
    October 20, 2015 at 3:57 am

    […] 11 tips to improve Angular performance […]

    Reply
  21. 11 Tips to Improve AngularJS Performance - DotInCare Blog says:
    October 19, 2015 at 9:54 am

    […] Minimize/Avoid Watchers […]

    Reply
  22. Confluence: UI Development says:
    August 17, 2015 at 1:27 pm

    11 Tips to Improve AngularJS Performance

    New link added to the UI Development homepage. 11

    Reply
  23. Confluence: UI Development says:
    August 17, 2015 at 1:24 pm

    UI Development Home

    Welcome to the UI Development home page. This is a

    Reply
  24. Confluence: Product and Content Integration says:
    July 10, 2015 at 6:27 am

    Eikon common – Performance Guidelines

    Performance Guidelines on ZawyaOnEikon Item Descri

    Reply
  25. Weekly links 2015-05-18 | Marcin Kossowski says:
    May 18, 2015 at 6:49 pm

    […] Improve angular performance […]

    Reply
  26. 11 Tips to Improve AngularJS Performance | Dinesh Ram Kali. says:
    April 30, 2015 at 7:46 pm

    […] via 11 Tips to Improve AngularJS Performance. […]

    Reply
  27. 1p – 11 Tips to Improve AngularJS Performance | Profit Goals says:
    April 29, 2015 at 1:44 am

    […] https://www.alexkras.com/11-tips-to-improve-angularjs-performance/ […]

    Reply

Copyright © 2021 · eleven40 Pro Theme on Genesis Framework · WordPress · Log in