SlideShare a Scribd company logo
Pierre-Yves Gicquel
Teo Eterovic
Introduction
Why are we here?
 AngularJS behave very well on light application
 Problems appears when DOM become complex
 Our use case : Ability
• Document management system
• <200 documents in DOM : no problem
• >350 documents in DOM : barely unusable
Part I
Performance pitfalls
The $digestive track
 When you bind a value to an element in Angular using
• ng-model,
• ng-repeat,
• {{foo}},
Angular creates a $watch on that value.
--angularjs.org
 All watched elements are added to a watch list
 When something changes on a scope (e.g model
changes, ng-click…), all watches
are triggered
When you watch too much
8-)
It is generally accepted that once the number of watchers reaches 2000+, an
application will start to suffer. AngularJS.org
“You can't really show more than about 2000 pieces of information to a human on a
single page. Anything more than that is really bad UI, and humans can't process
this anyway.”
-- Misko @ StackOverflow
Even more watches: ngClass, ngHide, ngIf, ngShow, ngStyle
Even more watches - ng-
repeat
ngRepeat directive instantiates a
template once per item [...] each
template instance gets its own
scope, where the given loop
variable is set to the current
collection item, and `$index` is set
to the item index or key. --
docs.angularjs.org
Even more watch - Filters
A convenient way to reduce the number of watchers is to limit their number by
filtering
An AngularJS filter in your HTML will execute (multiple times!) for every digest
cycle[4]
This means that the filtering function, or the filter will execute multiple times, even if
the underlying data or conditions have not changed.
Optimize
• by triggering your filter in your controller instead of having it directly in your
HTML.
• by injecting the filter service in application and if XXX is the service
XXXFilter
• showcase Ability filter by chapter
Show Case
 Showcase how the number of watches affect
performance
• http://plnkr.co/edit/jwrHVb?p=preview
 Showcase how the filters affects performance
• http://jsfiddle.net/m2jak8c8/
 Showcase how to write a manually triggered filter
Part II
Best practices
Part II
Best practices
 General principle
• Limit the cost of digest cycle
• E.g : if a scroll triggers a digest at each frame
• Objective 60 FPS => $digest time < 16ms
 Strategies
• Digest only when you need
• Limit number of watchers
• One way binding
• Remove watchers dynamically
• Watch only what is needed
• Make sure what is watched is cheap
• Don’t use ng-mousenter, mouseleave…
• Avoid watch invisible elements
• …
Digest only on the scopes
you need
 Third party plugins make model changes
“outside” AngularJS
 Its’s where $scope.$apply become
handy
 However $scope.$apply=~$rootScope.
$digest
 Instead we can use $scope.$digest,
which run digest only in the current
scope (and child)
Show case:
http://jsfiddle.net/fqbsdqub/
Limit number of watch : one way
binding
 Show a variable without attaching a watch to it
 Part of Angular since v1.3 before that bindonce library
• Use :: to enable one way binding
Example:
<div ng-repeat="stock in ::ctrl.stocks">{{::stock.name}}</div>
Showcase
http://plnkr.co/edit/jwrHVb?p=preview
Use compile over link in
directive- when possible
 When a directive appears inside of a repeater :
• compile is called only once
• link and the constructor are called once per iteration
 The link function is called as much times as there are cloned directives.
 When creating directives, try to get as much work done as possible in the
compile step
Best practice
• Any operation which can be shared among the instance of directives
should be moved to the compile function for performance reasons. --
angularjs docs
SHOWCASE
 https://jsfiddle.net/83M34/42/ (look at the console log)
Removing the Unneeded
Watches
To disable the watch just call the returned function:
myWatch();
Same process for $timeOut
These watchers are removed when $scope.$destroy()
var myWatch = $scope.$watch('someVariable',
function(newVal, oldVal) {
if (newVal === oldVal) { return; }
});
Removing the Unneeded
Watches-2
In the case of $rootScope.$watch, watchers are not
removed
You have to call explicitly on $scope.$destroy
otherwise they will stay
var myWatch = $rootScope.$watch('someVariable',
function(newVal, oldVal) {
if (newVal === oldVal) { return; }
});
$watch only what is needed
 Sometimes a deep $watch is needed, but not for the entire object you can
watch individual properties.
 By stripping out irrelevant data, we can make the comparison much faster
 $watch(someObject.someArray.length) vs $watch(someObject.someArray) or even
$watch(someObject) - deep watch
 In angular.js 1.1.4: watchCollections
• http://bennadel.github.io/JavaScript-Demos/demos/watch-vs-watch-collection/
.
$scope.$watch(‘bigObject’,myHandler, true);
// better
$scope.$watch(function($scope) {
return $scope.bigObject.foo.
fieldICareAbout;.
}, myHandler, true);
Make sure what is being
checked is cheap
 With frequent dirty checking, its inadvisable to place calls to complex
functions into Angular expressions
 An ng-click somewhere could trigger a lot of dirty checking.
 Precompute everything (don't do the computations and expressions in
watches )
• {{ computeTotal(data) }} - this function will be called in each
digest! Precompute the result, cache it, or make it static
Don't use ng-mouseenter,
ng-mouseleave, etc.
 Using ng-mouseenter/ng-mouseleave triggers the digest cycle
• In general avoid directive that are triggered very often
 Use CSS/ vanillaJS wherever you can to avoid this trigger
 “Using the built-in directives like ng-mouseenter AngularJS caused our view to
flicker. The browser frame rate was mostly below 30 frames per second. Using
pure jQuery to create animations and hover-effects solved this problem”
Showcase: http://plnkr.co/edit/sFsuqvPajnw1x2LahX7T?p=preview
Avoid watching invisible
elements - Use ng-if, not ng-
show
 ngShow/ngHide
• “The element is shown or hidden by removing or adding the `.ng-hide` CSS class
onto the element. The `.ng-hide` CSS class is predefined in AngularJS and sets the
display style to none (using an !important flag).” - ngShowHide.js Source Code
 ngIf
• one of the best features to come out of Angular 1.2
• If the expression evaluates to a false value then the element is removed from the
DOM,
• otherwise a clone of the element is reinserted into the DOM.
• when an element is removed using `ngIf` its scope is destroyed and a new scope is
created when the element is restored. pros: watches are destroyed too :)
• The scope created within `ngIf` inherits from its parent scope using [prototypal
inheritance]
 cons: performance hit as it fully recompiles the angularjs template when hidden/shown
Evaluate Only When
 slyEvaluateOnlyWhen – slyPreventEvaluationWhenHidden
• Directive for preventing all bound expressions in the current element and its children from
being evaluated unless the specified expression evaluates to a different object.
• Prevent evaluation if the current element is hidden
 a alternative for ngIf - you see the DOM but the watches are inactive
 can be used together with element visible to optimize watches
Prevent deep filtering
 Same as for watches
 filter on specific fields (prevent deep filtering)
 use cheap statements inside filters functions that execute fast or break the
function on the beginning if the condition is not valid
angular.module('MyFilters', [])
.filter('customfiler', function() {
return function(input) {
if (input.age < 18) return
input;
if (intensiveChecking(input))
transformInput(input);
else
return input;
};
});
angular.module('MyFilters', [])
.filter('customfiler', function() {
return function(input) {
if (intensiveChecking(input) &&
input.age > 18)
{
transformInput(input);
} else return input;
};
});
Optimizing ng-repeat:
The build-in tools
 Track-by
• `item in items track by item.id
• In older Angular
• Uses DOM caching / reuse - less DOM manipulations
• Now :
• “`item in items` is equivalent to `item in items track by $id(item)`” -- ngRepeat.js Source
Code(26.02.2015.)
• $id(item) can be costly, if server provides uid, better use it
 Limit to
• `ng-repeat=“item in items limitTo index”
• Limit maximum number of visible items
• Can be used to create a lazy load scroll
Direct DOM manipulation
with vanillaJS/JQuery
 Don’t do it if there is another way
 Pros:
• Fast
• No watches
• Needs a lot of engineering :)
 Cons:
• Can’t use the power of angular anymore
• ugly code
Optimizing ng-repeat :
Remove non-visible
elements
 Pagination
• Simple method to reduce the number of watches for large item sets -
together with DOM caching / reuse its a powerful tool
 Virtual Scroll - Angular-vs-Repeat
• PROS:
• VERY easy to use just add <div vs-repeat> above your ng-repeat and enjoy the performance boost
• CONS:
• Sometimes it works perfectly with simple item lists but as soon as the case is more complex a lot of
customization is needed and there is a great possibility that it will flicker (container scrolls and co)
• Problems with nested repeats - can be buggy
• Not easy to combine it it with lazy loading/infinitive scroll
 ShowCase
• http://kamilkp.github.io/angular-vs-repeat/#?tab=8
Infinitive scroll - Lazy
Loading
 ngInfiniteScroll - angular library
 Manually - track by and limitTo
 Demo :D
Open question : Use ng-bind
instead of {{}}
 Some debate but no clear answer on SO
• http://stackoverflow.com/questions/16125872/why-ng-bind-is-better-than-in-angular
 Jsperf seems to say {{}} is better
• https://jsperf.com/angular-bind-vs-brackets
 What is your opinion?
Measures
 To measure the time a list rendering takes an directive could be
used which logs the time by using the ng-repeat property
“$last”Manually - track by and limitTo
// Post repeat directive for logging the rendering time
angular.module('siApp.services').directive('postRepeatDirective',
['$timeout', '$log', 'TimeTracker',
function($timeout, $log, TimeTracker) {
return function(scope, element, attrs) {
if (scope.$last){
$timeout(function(){
var timeFinishedLoadingList = TimeTracker.reviewListLoaded();
var ref = new Date(timeFinishedLoadingList);
var end = new Date();
$log.debug("## DOM rendering list took: " + (end - ref) + " ms");
});
}
};
}
]);
<tr ng-repeat="item in items" post-repeat-directive>…</tr>
Measures
 Number of watches
 Digest delay
 Monitoring the digest circle lag/delay time of the rootScope or
the selected scope
var vScope = $0 || document.querySelector('[ng-app]');
angular.element(vScope).injector().invoke(function($rootScope
) {
var a = performance.now();
$rootScope.$apply();
console.log(performance.now()-a);
})
Measures - Tools
 Batarang
 Developer Tools profiler
 Ng-stats
FUTURE
 “Dirty checking can have performance issues, but the core
team can/will start using Object.observe as ES6/harmony
matures. As JS grows, a lot of Angular downsides will stop
being relevant” -- Some guy on Reddit a year ago(2014)
 Angular.js 2.0
• WatchTower.js
• Object.observe
Questions
 What is the blend between Performance optimization and
breaking Angular.js ?
 Overuse of optimizations - using Javascript/JQuery to handle
the view directly ?
 Is Angular.js really good for every application ?
 ....
REFERENCES
 [1] Counting the number of watchers on a page in angular.js
 [2] Databinding in AngularJS
 [3] Optimizing AngularJS: 1200ms to 35ms, Steven Czerwinksi
 [4] Optimizing ng-repeat in AngularJS
 [5,7] Optimizing a Large AngularJS Application,Karl Seamon, ng-conf
 [6] Improving Angular Dirty Checking Performance Doug Turnbull — April 24,
2014
 [8] The Digest Loop and $apply, ngBook
 [9] Supercharge AngularJS Performance Measurement and Tuning Sebastian
Fröstl && Damien Klinnert
 [10] Speeding up AngularJS apps with simple optimizations, Todd Motto, Aug 6,
2014
 [11] AngularJS Performance Tuning for Long Lists, 2013 Sebastian Fröstl,
September 10

More Related Content

PDF
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
PDF
Ultimate Introduction To AngularJS
PPTX
Angularjs Performance
PDF
Introduction to A-Frame
PDF
Zenly - Reverse geocoding
PDF
Webrender 1.0
PDF
AngularJS - Overcoming performance issues. Limits.
PPTX
Using The New Flash Stage3D Web Technology To Build Your Own Next 3D Browser ...
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
Ultimate Introduction To AngularJS
Angularjs Performance
Introduction to A-Frame
Zenly - Reverse geocoding
Webrender 1.0
AngularJS - Overcoming performance issues. Limits.
Using The New Flash Stage3D Web Technology To Build Your Own Next 3D Browser ...

What's hot (19)

PPTX
Angularjs Basics
PDF
Using ReactJS in AngularJS
PDF
Xamarin.android memory management gotchas
PDF
Boost your angular app with web workers
PDF
Building scalable applications with angular js
PDF
Effective memory management
PDF
Developing iOS REST Applications
PDF
Maze VR
KEY
Core animation
PPTX
Getting started with ReactJS
PPTX
A frame beginner lesson
PDF
Writing Virtual And Augmented Reality Apps With Web Technology
PDF
Angular Performance: Then, Now and the Future. Todd Motto
PPT
The Theory Of The Dom
PDF
ASP.NET MVC Internals
PDF
How to build an AngularJS backend-ready app WITHOUT BACKEND
PPTX
Vue js and Dyploma
PDF
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"
PDF
Writing testable code
Angularjs Basics
Using ReactJS in AngularJS
Xamarin.android memory management gotchas
Boost your angular app with web workers
Building scalable applications with angular js
Effective memory management
Developing iOS REST Applications
Maze VR
Core animation
Getting started with ReactJS
A frame beginner lesson
Writing Virtual And Augmented Reality Apps With Web Technology
Angular Performance: Then, Now and the Future. Todd Motto
The Theory Of The Dom
ASP.NET MVC Internals
How to build an AngularJS backend-ready app WITHOUT BACKEND
Vue js and Dyploma
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"
Writing testable code
Ad

Similar to Angular js meetup (20)

PPTX
Optimizing a large angular application (ng conf)
PPTX
Dive into Angular, part 3: Performance
PPTX
Optimizing Angular Performance in Enterprise Single Page Apps
PDF
Dragos Rusu - Angular JS - Overcoming Performance Issues - CodeCamp-10-may-2014
PPTX
AngularJS Best Practices
PDF
Javascript Memory leaks and Performance & Angular
PDF
AngularJS performance & production tips
PPTX
AngularJS.part1
PDF
AngularJS Basics
PDF
AngularJS Workshop
PDF
Optimizing AngularJS Application
PPTX
Bhuvi ppt zerobug
PDF
AngularJS in practice
PPTX
Tips for Angular Applications
PPTX
Angular js performance improvements
PPTX
Angular workshop - Full Development Guide
PDF
Advanced Tips & Tricks for using Angular JS
PPTX
Performances & SEO in AngularJS
PPTX
5 angularjs features
PPTX
ANGULARJS introduction components services and directives
Optimizing a large angular application (ng conf)
Dive into Angular, part 3: Performance
Optimizing Angular Performance in Enterprise Single Page Apps
Dragos Rusu - Angular JS - Overcoming Performance Issues - CodeCamp-10-may-2014
AngularJS Best Practices
Javascript Memory leaks and Performance & Angular
AngularJS performance & production tips
AngularJS.part1
AngularJS Basics
AngularJS Workshop
Optimizing AngularJS Application
Bhuvi ppt zerobug
AngularJS in practice
Tips for Angular Applications
Angular js performance improvements
Angular workshop - Full Development Guide
Advanced Tips & Tricks for using Angular JS
Performances & SEO in AngularJS
5 angularjs features
ANGULARJS introduction components services and directives
Ad

Recently uploaded (20)

PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Approach and Philosophy of On baking technology
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Machine learning based COVID-19 study performance prediction
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
Big Data Technologies - Introduction.pptx
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
KodekX | Application Modernization Development
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
A Presentation on Artificial Intelligence
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPT
Teaching material agriculture food technology
PDF
Network Security Unit 5.pdf for BCA BBA.
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Understanding_Digital_Forensics_Presentation.pptx
Approach and Philosophy of On baking technology
The Rise and Fall of 3GPP – Time for a Sabbatical?
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Encapsulation_ Review paper, used for researhc scholars
Machine learning based COVID-19 study performance prediction
Chapter 3 Spatial Domain Image Processing.pdf
20250228 LYD VKU AI Blended-Learning.pptx
Big Data Technologies - Introduction.pptx
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
KodekX | Application Modernization Development
Dropbox Q2 2025 Financial Results & Investor Presentation
Building Integrated photovoltaic BIPV_UPV.pdf
A Presentation on Artificial Intelligence
Advanced methodologies resolving dimensionality complications for autism neur...
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Teaching material agriculture food technology
Network Security Unit 5.pdf for BCA BBA.

Angular js meetup

  • 2. Introduction Why are we here?  AngularJS behave very well on light application  Problems appears when DOM become complex  Our use case : Ability • Document management system • <200 documents in DOM : no problem • >350 documents in DOM : barely unusable
  • 4. The $digestive track  When you bind a value to an element in Angular using • ng-model, • ng-repeat, • {{foo}}, Angular creates a $watch on that value. --angularjs.org  All watched elements are added to a watch list  When something changes on a scope (e.g model changes, ng-click…), all watches are triggered
  • 5. When you watch too much 8-) It is generally accepted that once the number of watchers reaches 2000+, an application will start to suffer. AngularJS.org “You can't really show more than about 2000 pieces of information to a human on a single page. Anything more than that is really bad UI, and humans can't process this anyway.” -- Misko @ StackOverflow Even more watches: ngClass, ngHide, ngIf, ngShow, ngStyle
  • 6. Even more watches - ng- repeat ngRepeat directive instantiates a template once per item [...] each template instance gets its own scope, where the given loop variable is set to the current collection item, and `$index` is set to the item index or key. -- docs.angularjs.org
  • 7. Even more watch - Filters A convenient way to reduce the number of watchers is to limit their number by filtering An AngularJS filter in your HTML will execute (multiple times!) for every digest cycle[4] This means that the filtering function, or the filter will execute multiple times, even if the underlying data or conditions have not changed. Optimize • by triggering your filter in your controller instead of having it directly in your HTML. • by injecting the filter service in application and if XXX is the service XXXFilter • showcase Ability filter by chapter
  • 8. Show Case  Showcase how the number of watches affect performance • http://plnkr.co/edit/jwrHVb?p=preview  Showcase how the filters affects performance • http://jsfiddle.net/m2jak8c8/  Showcase how to write a manually triggered filter
  • 10. Part II Best practices  General principle • Limit the cost of digest cycle • E.g : if a scroll triggers a digest at each frame • Objective 60 FPS => $digest time < 16ms  Strategies • Digest only when you need • Limit number of watchers • One way binding • Remove watchers dynamically • Watch only what is needed • Make sure what is watched is cheap • Don’t use ng-mousenter, mouseleave… • Avoid watch invisible elements • …
  • 11. Digest only on the scopes you need  Third party plugins make model changes “outside” AngularJS  Its’s where $scope.$apply become handy  However $scope.$apply=~$rootScope. $digest  Instead we can use $scope.$digest, which run digest only in the current scope (and child) Show case: http://jsfiddle.net/fqbsdqub/
  • 12. Limit number of watch : one way binding  Show a variable without attaching a watch to it  Part of Angular since v1.3 before that bindonce library • Use :: to enable one way binding Example: <div ng-repeat="stock in ::ctrl.stocks">{{::stock.name}}</div> Showcase http://plnkr.co/edit/jwrHVb?p=preview
  • 13. Use compile over link in directive- when possible  When a directive appears inside of a repeater : • compile is called only once • link and the constructor are called once per iteration  The link function is called as much times as there are cloned directives.  When creating directives, try to get as much work done as possible in the compile step Best practice • Any operation which can be shared among the instance of directives should be moved to the compile function for performance reasons. -- angularjs docs SHOWCASE  https://jsfiddle.net/83M34/42/ (look at the console log)
  • 14. Removing the Unneeded Watches To disable the watch just call the returned function: myWatch(); Same process for $timeOut These watchers are removed when $scope.$destroy() var myWatch = $scope.$watch('someVariable', function(newVal, oldVal) { if (newVal === oldVal) { return; } });
  • 15. Removing the Unneeded Watches-2 In the case of $rootScope.$watch, watchers are not removed You have to call explicitly on $scope.$destroy otherwise they will stay var myWatch = $rootScope.$watch('someVariable', function(newVal, oldVal) { if (newVal === oldVal) { return; } });
  • 16. $watch only what is needed  Sometimes a deep $watch is needed, but not for the entire object you can watch individual properties.  By stripping out irrelevant data, we can make the comparison much faster  $watch(someObject.someArray.length) vs $watch(someObject.someArray) or even $watch(someObject) - deep watch  In angular.js 1.1.4: watchCollections • http://bennadel.github.io/JavaScript-Demos/demos/watch-vs-watch-collection/ . $scope.$watch(‘bigObject’,myHandler, true); // better $scope.$watch(function($scope) { return $scope.bigObject.foo. fieldICareAbout;. }, myHandler, true);
  • 17. Make sure what is being checked is cheap  With frequent dirty checking, its inadvisable to place calls to complex functions into Angular expressions  An ng-click somewhere could trigger a lot of dirty checking.  Precompute everything (don't do the computations and expressions in watches ) • {{ computeTotal(data) }} - this function will be called in each digest! Precompute the result, cache it, or make it static
  • 18. Don't use ng-mouseenter, ng-mouseleave, etc.  Using ng-mouseenter/ng-mouseleave triggers the digest cycle • In general avoid directive that are triggered very often  Use CSS/ vanillaJS wherever you can to avoid this trigger  “Using the built-in directives like ng-mouseenter AngularJS caused our view to flicker. The browser frame rate was mostly below 30 frames per second. Using pure jQuery to create animations and hover-effects solved this problem” Showcase: http://plnkr.co/edit/sFsuqvPajnw1x2LahX7T?p=preview
  • 19. Avoid watching invisible elements - Use ng-if, not ng- show  ngShow/ngHide • “The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined in AngularJS and sets the display style to none (using an !important flag).” - ngShowHide.js Source Code  ngIf • one of the best features to come out of Angular 1.2 • If the expression evaluates to a false value then the element is removed from the DOM, • otherwise a clone of the element is reinserted into the DOM. • when an element is removed using `ngIf` its scope is destroyed and a new scope is created when the element is restored. pros: watches are destroyed too :) • The scope created within `ngIf` inherits from its parent scope using [prototypal inheritance]  cons: performance hit as it fully recompiles the angularjs template when hidden/shown
  • 20. Evaluate Only When  slyEvaluateOnlyWhen – slyPreventEvaluationWhenHidden • Directive for preventing all bound expressions in the current element and its children from being evaluated unless the specified expression evaluates to a different object. • Prevent evaluation if the current element is hidden  a alternative for ngIf - you see the DOM but the watches are inactive  can be used together with element visible to optimize watches
  • 21. Prevent deep filtering  Same as for watches  filter on specific fields (prevent deep filtering)  use cheap statements inside filters functions that execute fast or break the function on the beginning if the condition is not valid angular.module('MyFilters', []) .filter('customfiler', function() { return function(input) { if (input.age < 18) return input; if (intensiveChecking(input)) transformInput(input); else return input; }; }); angular.module('MyFilters', []) .filter('customfiler', function() { return function(input) { if (intensiveChecking(input) && input.age > 18) { transformInput(input); } else return input; }; });
  • 22. Optimizing ng-repeat: The build-in tools  Track-by • `item in items track by item.id • In older Angular • Uses DOM caching / reuse - less DOM manipulations • Now : • “`item in items` is equivalent to `item in items track by $id(item)`” -- ngRepeat.js Source Code(26.02.2015.) • $id(item) can be costly, if server provides uid, better use it  Limit to • `ng-repeat=“item in items limitTo index” • Limit maximum number of visible items • Can be used to create a lazy load scroll
  • 23. Direct DOM manipulation with vanillaJS/JQuery  Don’t do it if there is another way  Pros: • Fast • No watches • Needs a lot of engineering :)  Cons: • Can’t use the power of angular anymore • ugly code
  • 24. Optimizing ng-repeat : Remove non-visible elements  Pagination • Simple method to reduce the number of watches for large item sets - together with DOM caching / reuse its a powerful tool  Virtual Scroll - Angular-vs-Repeat • PROS: • VERY easy to use just add <div vs-repeat> above your ng-repeat and enjoy the performance boost • CONS: • Sometimes it works perfectly with simple item lists but as soon as the case is more complex a lot of customization is needed and there is a great possibility that it will flicker (container scrolls and co) • Problems with nested repeats - can be buggy • Not easy to combine it it with lazy loading/infinitive scroll  ShowCase • http://kamilkp.github.io/angular-vs-repeat/#?tab=8
  • 25. Infinitive scroll - Lazy Loading  ngInfiniteScroll - angular library  Manually - track by and limitTo  Demo :D
  • 26. Open question : Use ng-bind instead of {{}}  Some debate but no clear answer on SO • http://stackoverflow.com/questions/16125872/why-ng-bind-is-better-than-in-angular  Jsperf seems to say {{}} is better • https://jsperf.com/angular-bind-vs-brackets  What is your opinion?
  • 27. Measures  To measure the time a list rendering takes an directive could be used which logs the time by using the ng-repeat property “$last”Manually - track by and limitTo // Post repeat directive for logging the rendering time angular.module('siApp.services').directive('postRepeatDirective', ['$timeout', '$log', 'TimeTracker', function($timeout, $log, TimeTracker) { return function(scope, element, attrs) { if (scope.$last){ $timeout(function(){ var timeFinishedLoadingList = TimeTracker.reviewListLoaded(); var ref = new Date(timeFinishedLoadingList); var end = new Date(); $log.debug("## DOM rendering list took: " + (end - ref) + " ms"); }); } }; } ]); <tr ng-repeat="item in items" post-repeat-directive>…</tr>
  • 28. Measures  Number of watches  Digest delay  Monitoring the digest circle lag/delay time of the rootScope or the selected scope var vScope = $0 || document.querySelector('[ng-app]'); angular.element(vScope).injector().invoke(function($rootScope ) { var a = performance.now(); $rootScope.$apply(); console.log(performance.now()-a); })
  • 29. Measures - Tools  Batarang  Developer Tools profiler  Ng-stats
  • 30. FUTURE  “Dirty checking can have performance issues, but the core team can/will start using Object.observe as ES6/harmony matures. As JS grows, a lot of Angular downsides will stop being relevant” -- Some guy on Reddit a year ago(2014)  Angular.js 2.0 • WatchTower.js • Object.observe
  • 31. Questions  What is the blend between Performance optimization and breaking Angular.js ?  Overuse of optimizations - using Javascript/JQuery to handle the view directly ?  Is Angular.js really good for every application ?  ....
  • 32. REFERENCES  [1] Counting the number of watchers on a page in angular.js  [2] Databinding in AngularJS  [3] Optimizing AngularJS: 1200ms to 35ms, Steven Czerwinksi  [4] Optimizing ng-repeat in AngularJS  [5,7] Optimizing a Large AngularJS Application,Karl Seamon, ng-conf  [6] Improving Angular Dirty Checking Performance Doug Turnbull — April 24, 2014  [8] The Digest Loop and $apply, ngBook  [9] Supercharge AngularJS Performance Measurement and Tuning Sebastian Fröstl && Damien Klinnert  [10] Speeding up AngularJS apps with simple optimizations, Todd Motto, Aug 6, 2014  [11] AngularJS Performance Tuning for Long Lists, 2013 Sebastian Fröstl, September 10

Editor's Notes

  • #5: When you apply, the digest loop will be trigered with all elements of the watch list being processed Then when everything is done a new digest is performed to check that the performance are stable
  • #6: The problem is that it is quite easy to create lot of watches, lot of directive actually creating watch If you mix this with ng-repeat you can easily end up with more than 2000 watches
  • #7: If an element have 5 watch and is repeated 10 times, then you will end with 50 watches Filter will reduce the number of watches since elements are not created