Chapter 11
We can supply a third true argument to the $watch method in order to indicate that
AngularJS should use deep-comparison for objects. In this case the whole object
(every property of it) is compared using the angular.equal function. In the deep-
watching mode the comparison process will be slower. Not only does this AngularJS
need to copy (angular.copy) and save the whole object for further comparisons.
This is obviously wasteful from the memory consumption point of view as we are
constantly copying and storing all the properties of a given object while being only
interested in a subset of them.
Fortunately there are several alternatives to the deep-watching, and those can be
easily applied if we are only concerned with a subset of object's properties. To start,
we could simply watch results of the full name calculation:
$scope.$watch(function(scope) {
return scope.user.firstName + ' ' + scope.user.lastName;
}, function (newFullName) {
$scope.fullName = newFullName;
});
The advantage here is that only final results of the full name calculation are stored
in memory for further comparisons. The downside is that the full name calculation
takes place in each and every $digest loop turn, even if the user's properties don't
change at all. By employing this technique we can save memory in expense of
additional CPU cycles. As a side note, the same effect could be achieved by invoking
a function from an AngularJS expression in a template:
{{fullName()}}
Where the fullName() function would be defined on a scope like:
$scope.fullName = function () {
return $scope.user.firstName + ' ' + $scope.user.lastName;
};
Deep-watching has a double performance penalty. Not only does
AngularJS need to store a copy of an object in memory for further
comparisons but the actual equality check is slower as well. Try to
use alternatives presented here if you are only interested in a subset
of properties for a given object.
Performance tuning is a delicate balancing act. This is very well visible in the
earlier examples where we need to often trade memory bytes for CPU cycles. An
optimal solution to be applied in your application will depend on performance
bottlenecks identified.