際際滷

際際滷Share a Scribd company logo
Performance
Angularjs
What is Angulars biggest
performance bottleneck?
The $digest cycle (a.k.a. dirty
checking)
How the $digest cycle works
When Angular (or you) calls $scope.$apply, this kicks off the $digest cycle.
$rootScope
$scope
$scope $scope.$apply
How the $digest cycle works
During the digest cycle, Angular will check every $scope for all Angular
bindings to see if any have changed.
$rootScope
$scope
ngBinding
ngBinding
$scope
ngBinding
Changed?
How the $digest cycle works
If any binding has changed, Angular will finish the current cycle and then start
the loop over again checking to see if the change affected other bindings.
$rootScope
$scope
ngBinding
ngBinding
$scope
ngBinding
Changed? Yes
Changed? No
Changed? No (restart cycle)
How the $digest cycle works
A $digest cycle will only complete when no Angular bindings have changed.
$rootScope
$scope
ngBinding
ngBinding
$scope
ngBinding
Changed? No
Changed? No
Changed? No ($digest completed)
How the $digest cycle works
This means that any change will cause the $digest cycle to run at least twice;
once to update the binding and again to ensure that no other bindings were
changed.
Example: If your app has 200 bindings, Angular will run at least 400 dirty
checks when a binding changes.
Improving $digest performance
¢ Reduce number of bindings
o use native DOM
o ng-if instead of ng-hide
o clean up $watchers when no longer needed
o avoid ng-repeat where possible
o avoid filters where possible
¢ Simplify logic in bindings
o use simple comparisons
o avoid binding to functions where possible
Use Native DOM
Just because you are using Angular as a framework does not mean you have
to do everything the ^Angular ̄ way.
One of the nice things about Angular is that you can choose when and when
not to use it.
If your DOM won¨t change very often or only at certain, controllable times, you
can use native DOM manipulation instead of relying on Angular bindings.
Code Example
Use ng-if instead of ng-show
ng-show just hides the DOM using display:none; However, this keeps all the
bindings of the element and it¨s children.
ng-if removes the DOM and all of it¨s bindings.
caveat: ng-if manipulates the DOM, which can become more expensive if the
ng-if changes state a lot.
Clean up $watchers
Sometimes you only need to $watch for a change once and then no longer
need to watch for any changes anymore.
The $scope.$watch() function returns a function that you can use to remove the
watch binding.
var unWatch = $scope.$watch(`contact¨, function() {
// do some logic
unWatch(); // unbind watcher as no longer needed
});
Avoid ng-repeat
ng-repeat has some big performance problems, especially with large data sets.
ng-repeat adds lots of bindings to the DOM (1 for itself + n bindings inside the
repeat * num of items in collection)
<div ng-repeat= ̄item in list ̄>
<div>{{hello}} <span>{{goodbye}}</span></div>
</div>
bindings = (2 bindings * list length) + ng-repeat [list of 10 items = 21 bindings]
Avoid ng-repeat
Each of these bindings will be checked on every $digest, even if the list didn¨t
change.
Even worse, when the list does change, it will manipulate the DOM, which
depending on what you are doing, can be expensive.
This is the exact same problem with filters.
Avoid filters
Filters will be run on every $digest, even if the binding attached to the filter
didn¨t change.
Filters such as lowercase, date, and orderBy are bad because they will
transform the DOM at every $digest.
Instead, you can use the $filter provider and save the filtered result to be
displayed into the DOM.
Code Example
Use Simple Logic in Bindings
Because dirty-checking requires a comparison check of the old value to the
new value, the faster the comparison the faster the $digest cycle will run.
Comparisons to primitives and shallow equality of objects are the fastest.
Deep equality of objects are slow (so don¨t do it).
Avoid Functions in Bindings
Functions in bindings are bad from a performance point of view.
A function inside a binding ( {{fn()}} ) will be called at every $digest (having
function call overhead).
A function inside an ng-repeat will be called for every item in the collection.
This doesn¨t mean that functions inside ng-click are bad, since it will only be
called when the element is clicked on.
Avoid Functions in Bindings
Types of Functions:
¢ Just returns variable - get rid of the function and just use the variable
directly
¢ Performs some logic - try to pre-compute the logic once and then save the
result to be used in a binding

More Related Content

Angularjs Performance

  • 2. What is Angulars biggest performance bottleneck?
  • 3. The $digest cycle (a.k.a. dirty checking)
  • 4. How the $digest cycle works When Angular (or you) calls $scope.$apply, this kicks off the $digest cycle. $rootScope $scope $scope $scope.$apply
  • 5. How the $digest cycle works During the digest cycle, Angular will check every $scope for all Angular bindings to see if any have changed. $rootScope $scope ngBinding ngBinding $scope ngBinding Changed?
  • 6. How the $digest cycle works If any binding has changed, Angular will finish the current cycle and then start the loop over again checking to see if the change affected other bindings. $rootScope $scope ngBinding ngBinding $scope ngBinding Changed? Yes Changed? No Changed? No (restart cycle)
  • 7. How the $digest cycle works A $digest cycle will only complete when no Angular bindings have changed. $rootScope $scope ngBinding ngBinding $scope ngBinding Changed? No Changed? No Changed? No ($digest completed)
  • 8. How the $digest cycle works This means that any change will cause the $digest cycle to run at least twice; once to update the binding and again to ensure that no other bindings were changed. Example: If your app has 200 bindings, Angular will run at least 400 dirty checks when a binding changes.
  • 9. Improving $digest performance ¢ Reduce number of bindings o use native DOM o ng-if instead of ng-hide o clean up $watchers when no longer needed o avoid ng-repeat where possible o avoid filters where possible ¢ Simplify logic in bindings o use simple comparisons o avoid binding to functions where possible
  • 10. Use Native DOM Just because you are using Angular as a framework does not mean you have to do everything the ^Angular ̄ way. One of the nice things about Angular is that you can choose when and when not to use it. If your DOM won¨t change very often or only at certain, controllable times, you can use native DOM manipulation instead of relying on Angular bindings. Code Example
  • 11. Use ng-if instead of ng-show ng-show just hides the DOM using display:none; However, this keeps all the bindings of the element and it¨s children. ng-if removes the DOM and all of it¨s bindings. caveat: ng-if manipulates the DOM, which can become more expensive if the ng-if changes state a lot.
  • 12. Clean up $watchers Sometimes you only need to $watch for a change once and then no longer need to watch for any changes anymore. The $scope.$watch() function returns a function that you can use to remove the watch binding. var unWatch = $scope.$watch(`contact¨, function() { // do some logic unWatch(); // unbind watcher as no longer needed });
  • 13. Avoid ng-repeat ng-repeat has some big performance problems, especially with large data sets. ng-repeat adds lots of bindings to the DOM (1 for itself + n bindings inside the repeat * num of items in collection) <div ng-repeat= ̄item in list ̄> <div>{{hello}} <span>{{goodbye}}</span></div> </div> bindings = (2 bindings * list length) + ng-repeat [list of 10 items = 21 bindings]
  • 14. Avoid ng-repeat Each of these bindings will be checked on every $digest, even if the list didn¨t change. Even worse, when the list does change, it will manipulate the DOM, which depending on what you are doing, can be expensive. This is the exact same problem with filters.
  • 15. Avoid filters Filters will be run on every $digest, even if the binding attached to the filter didn¨t change. Filters such as lowercase, date, and orderBy are bad because they will transform the DOM at every $digest. Instead, you can use the $filter provider and save the filtered result to be displayed into the DOM. Code Example
  • 16. Use Simple Logic in Bindings Because dirty-checking requires a comparison check of the old value to the new value, the faster the comparison the faster the $digest cycle will run. Comparisons to primitives and shallow equality of objects are the fastest. Deep equality of objects are slow (so don¨t do it).
  • 17. Avoid Functions in Bindings Functions in bindings are bad from a performance point of view. A function inside a binding ( {{fn()}} ) will be called at every $digest (having function call overhead). A function inside an ng-repeat will be called for every item in the collection. This doesn¨t mean that functions inside ng-click are bad, since it will only be called when the element is clicked on.
  • 18. Avoid Functions in Bindings Types of Functions: ¢ Just returns variable - get rid of the function and just use the variable directly ¢ Performs some logic - try to pre-compute the logic once and then save the result to be used in a binding