AngularJS $watch vs $watchCollection: which is better for performance? AngularJS $watch vs $watchCollection: which is better for performance? angularjs angularjs

AngularJS $watch vs $watchCollection: which is better for performance?


$watch() will be triggered by:

$scope.myArray = [];$scope.myArray = null;$scope.myArray = someOtherArray;

$watchCollection() will be triggered by everything above AND:

$scope.myArray.push({}); // add element$scope.myArray.splice(0, 1); // remove element$scope.myArray[0] = {}; // assign index to different value

$watch(..., true) will be triggered by EVERYTHING above AND:

$scope.myArray[0].someProperty = "someValue";

JUST ONE MORE THING...

$watch() is the only one that fires when an array is replaced with another with the same exact content. For example:

$scope.myArray = ["Apples", "Bananas", "Orange" ];var newArray = [];newArray.push("Apples");newArray.push("Bananas");newArray.push("Orange");$scope.myArray = newArray;

Below is a link to an example JSFiddle that uses all the different watch combinations and outputs log messages to indicate which "watches" were triggered:

http://jsfiddle.net/luisperezphd/2zj9k872/


The $watchCollection() function is a sort-of mid-ground between the two $watch() configurations above. It's more in-depth than the vanilla $watch() function; but, it's not nearly as expensive as the deep-equality $watch() function. Like the $watch() function, the $watchCollection() works by comparing physical object references; however, unlike the $watch() function, the $watchCollection() goes one-level deep and performs an additional, shallow reference check of the top level items in the collection.

see this explanation


$watchCollection is optimized for vector arrays [] where elements can be push

and $watch is good for associative arrays objects {}

$watchCollection will not watch for depth changes, is like watch with objectEquality set to false.

If you already know to structure of the depth you can optimize like this:

  // ctrl watch ?  $scope.$watch('filters', function(newVal, oldVal) {    if(newVal !== oldVal) {      // call with updated filters    }  });  // ctrl watch ?  $scope.$watch('filters.info', function(newVal, oldVal) {    if(newVal !== oldVal) {      // call with updated filters    }  });