SlideShare a Scribd company logo
1 of 32
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

What's hot

Using ReactJS in AngularJS
Using ReactJS in AngularJSUsing ReactJS in AngularJS
Using ReactJS in AngularJSBoris Dinkevich
 
Xamarin.android memory management gotchas
Xamarin.android memory management gotchasXamarin.android memory management gotchas
Xamarin.android memory management gotchasAlec Tucker
 
Building scalable applications with angular js
Building scalable applications with angular jsBuilding scalable applications with angular js
Building scalable applications with angular jsAndrew Alpert
 
Effective memory management
Effective memory managementEffective memory management
Effective memory managementDenis Zhuchinski
 
Developing iOS REST Applications
Developing iOS REST ApplicationsDeveloping iOS REST Applications
Developing iOS REST Applicationslmrei
 
Getting started with ReactJS
Getting started with ReactJSGetting started with ReactJS
Getting started with ReactJSKrishna Sunuwar
 
A frame beginner lesson
A frame beginner lessonA frame beginner lesson
A frame beginner lessonDaosheng Mu
 
Writing Virtual And Augmented Reality Apps With Web Technology
Writing Virtual And Augmented Reality Apps With Web TechnologyWriting Virtual And Augmented Reality Apps With Web Technology
Writing Virtual And Augmented Reality Apps With Web TechnologyMichaela Lehr
 
Angular Performance: Then, Now and the Future. Todd Motto
Angular Performance: Then, Now and the Future. Todd MottoAngular Performance: Then, Now and the Future. Todd Motto
Angular Performance: Then, Now and the Future. Todd MottoFuture Insights
 
The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Domkaven yan
 
ASP.NET MVC Internals
ASP.NET MVC InternalsASP.NET MVC Internals
ASP.NET MVC InternalsVitaly Baum
 
How to build an AngularJS backend-ready app WITHOUT BACKEND
How to build an AngularJS backend-ready app WITHOUT BACKEND How to build an AngularJS backend-ready app WITHOUT BACKEND
How to build an AngularJS backend-ready app WITHOUT BACKEND Enrique Oriol Bermúdez
 
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"Григорий Шехет "Treasure hunt in the land of Reactive frameworks"
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"Fwdays
 

What's hot (19)

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

Viewers also liked

tax sheltered_insurance
tax sheltered_insurancetax sheltered_insurance
tax sheltered_insuranceAndrew Meyers
 
Presentation on water cycle
Presentation on water cyclePresentation on water cycle
Presentation on water cyclecasubrata
 
Presentacion AromaClima Junio 2016
Presentacion AromaClima Junio 2016Presentacion AromaClima Junio 2016
Presentacion AromaClima Junio 2016Esther Diez
 

Viewers also liked (10)

Stephen miller resume
Stephen miller resumeStephen miller resume
Stephen miller resume
 
Stephen miller resume
Stephen miller resumeStephen miller resume
Stephen miller resume
 
What can OER do for uaa
What can OER do for uaaWhat can OER do for uaa
What can OER do for uaa
 
tax sheltered_insurance
tax sheltered_insurancetax sheltered_insurance
tax sheltered_insurance
 
Presentation on water cycle
Presentation on water cyclePresentation on water cycle
Presentation on water cycle
 
Presentacion AromaClima Junio 2016
Presentacion AromaClima Junio 2016Presentacion AromaClima Junio 2016
Presentacion AromaClima Junio 2016
 
Vehicle
VehicleVehicle
Vehicle
 
Stephen miller resume
Stephen miller resumeStephen miller resume
Stephen miller resume
 
Stephen miller resume
Stephen miller resumeStephen miller resume
Stephen miller resume
 
Stephen miller resume
Stephen miller resumeStephen miller resume
Stephen miller resume
 

Similar to angularjsmeetup-150303044616-conversion-gate01

AngularJs presentation
AngularJs presentation AngularJs presentation
AngularJs presentation Phan Tuan
 
Integrating AngularJS into the Campus CMS
Integrating AngularJS into the Campus CMSIntegrating AngularJS into the Campus CMS
Integrating AngularJS into the Campus CMSTom Borger
 
Advanced Tips & Tricks for using Angular JS
Advanced Tips & Tricks for using Angular JSAdvanced Tips & Tricks for using Angular JS
Advanced Tips & Tricks for using Angular JSSimon Guest
 
Workshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIWorkshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIVisual Engineering
 
Bhuvi ppt zerobug
Bhuvi ppt zerobugBhuvi ppt zerobug
Bhuvi ppt zerobugBhuviS3
 
AngularJS Beginners Workshop
AngularJS Beginners WorkshopAngularJS Beginners Workshop
AngularJS Beginners WorkshopSathish VJ
 
Gitter marionette deck
Gitter marionette deckGitter marionette deck
Gitter marionette deckMike Bartlett
 
AngularJS One Day Workshop
AngularJS One Day WorkshopAngularJS One Day Workshop
AngularJS One Day WorkshopShyam Seshadri
 
Angular - Chapter 5 - Directives
 Angular - Chapter 5 - Directives Angular - Chapter 5 - Directives
Angular - Chapter 5 - DirectivesWebStackAcademy
 
Building React Applications with Redux
Building React Applications with ReduxBuilding React Applications with Redux
Building React Applications with ReduxFITC
 
Angularjs for kolkata drupal meetup
Angularjs for kolkata drupal meetupAngularjs for kolkata drupal meetup
Angularjs for kolkata drupal meetupGoutam Dey
 
Dive into Angular, part 3: Performance
Dive into Angular, part 3: PerformanceDive into Angular, part 3: Performance
Dive into Angular, part 3: PerformanceOleksii Prohonnyi
 
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...JavaScripters Community
 
Coffee@DBG - Exploring Angular JS
Coffee@DBG - Exploring Angular JSCoffee@DBG - Exploring Angular JS
Coffee@DBG - Exploring Angular JSDeepu S Nath
 
Web technologies-course 12.pptx
Web technologies-course 12.pptxWeb technologies-course 12.pptx
Web technologies-course 12.pptxStefan Oprea
 
Zend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinarZend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinarYonni Mendes
 
Angular JS, A dive to concepts
Angular JS, A dive to conceptsAngular JS, A dive to concepts
Angular JS, A dive to conceptsAbhishek Sur
 

Similar to angularjsmeetup-150303044616-conversion-gate01 (20)

AngularJs presentation
AngularJs presentation AngularJs presentation
AngularJs presentation
 
Integrating AngularJS into the Campus CMS
Integrating AngularJS into the Campus CMSIntegrating AngularJS into the Campus CMS
Integrating AngularJS into the Campus CMS
 
Advanced Tips & Tricks for using Angular JS
Advanced Tips & Tricks for using Angular JSAdvanced Tips & Tricks for using Angular JS
Advanced Tips & Tricks for using Angular JS
 
Workshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIWorkshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte III
 
Intro to AngularJs
Intro to AngularJsIntro to AngularJs
Intro to AngularJs
 
Bhuvi ppt zerobug
Bhuvi ppt zerobugBhuvi ppt zerobug
Bhuvi ppt zerobug
 
AngularJS Beginners Workshop
AngularJS Beginners WorkshopAngularJS Beginners Workshop
AngularJS Beginners Workshop
 
Gitter marionette deck
Gitter marionette deckGitter marionette deck
Gitter marionette deck
 
AngularJs Crash Course
AngularJs Crash CourseAngularJs Crash Course
AngularJs Crash Course
 
AngularJS One Day Workshop
AngularJS One Day WorkshopAngularJS One Day Workshop
AngularJS One Day Workshop
 
Angular - Chapter 5 - Directives
 Angular - Chapter 5 - Directives Angular - Chapter 5 - Directives
Angular - Chapter 5 - Directives
 
Building React Applications with Redux
Building React Applications with ReduxBuilding React Applications with Redux
Building React Applications with Redux
 
Angularjs for kolkata drupal meetup
Angularjs for kolkata drupal meetupAngularjs for kolkata drupal meetup
Angularjs for kolkata drupal meetup
 
AngularJS Scopes
AngularJS ScopesAngularJS Scopes
AngularJS Scopes
 
Dive into Angular, part 3: Performance
Dive into Angular, part 3: PerformanceDive into Angular, part 3: Performance
Dive into Angular, part 3: Performance
 
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
 
Coffee@DBG - Exploring Angular JS
Coffee@DBG - Exploring Angular JSCoffee@DBG - Exploring Angular JS
Coffee@DBG - Exploring Angular JS
 
Web technologies-course 12.pptx
Web technologies-course 12.pptxWeb technologies-course 12.pptx
Web technologies-course 12.pptx
 
Zend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinarZend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinar
 
Angular JS, A dive to concepts
Angular JS, A dive to conceptsAngular JS, A dive to concepts
Angular JS, A dive to concepts
 

angularjsmeetup-150303044616-conversion-gate01

  • 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

  1. 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
  2. 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
  3. 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