AngularJS $watch vs $watchCollection: wat is beter voor de prestaties?

Voor het bekijken van een objectbereikvariabele: is $scope.$watchmet objectEqualityingesteld op true OF $scope.$watchCollectionbeter?

Voor een $scopeobjectvariabele (zoals 15 attributen, sommige genest 2 niveaus diep) bijgewerkt met invoerelementen en ng-modelin de weergave, hoe slecht is $scope.$watchmet objectEqualityingesteld op true? Is dit iets belangrijks om te vermijden?

Is $watchCollectioneen betere oplossing?

Ik ben op zoek naar gemakkelijke overwinningen om de prestaties van mijn AngularJS-app te verbeteren (ik zit nog steeds vast op v1.2.2).

 // ctrl scope var
  $scope.filters = {
    name: '',
    info: {test: '', foo: '', bar: ''},
    yep: ''
    // etc ...
  }
  // ctrl watch ?
  $scope.$watch('filters', function(newVal, oldVal) {
    if(newVal !== oldVal) {
      // call with updated filters
    }
  }, true);
  // or ctrl watch collection ?
  $scope.$watchCollection('filters', function(newVal, oldVal) {
    if(newVal !== oldVal) {
      // call with updated filters
    }
  });
  // view input with ng-model
  <input type="text" ng-model="filters.name" />
  <input type="text" ng-model="filters.info.test" />
  <input type="text" ng-model="filters.yep" />
  // etc ...  

Antwoord 1, autoriteit 100%

De functie $watchCollection()is een soort middenweg tussen de
twee $watch()configuraties hierboven. Het is meer diepgaand dan de
vanille $watch() functie; maar het is lang niet zo duur als de
deep-equality $watch()functie. Net als de functie $watch(), is de
$watchCollection()werkt door fysieke objectreferenties te vergelijken;
echter, in tegenstelling tot de functie $watch(), gaat de $watchCollection()
één niveau diep en voert een extra, ondiepe referentiecontrole uit van
de items van het hoogste niveau in de collectie.

zie deze uitleg


Antwoord 2, autoriteit 95%

$watch()wordt geactiveerd door:

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

$watchCollection()wordt geactiveerd door alles hierboven EN:

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

$watch(…, true)wordt geactiveerd door ALLES hierboven EN:

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

EEN NOG MEER…

$watch()is de enige die wordt geactiveerd wanneer een array wordt vervangen door een andere met exact dezelfde inhoud. Bijvoorbeeld:

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

Hieronder staat een link naar een voorbeeld-JSFiddle die alle verschillende horlogecombinaties gebruikt en logberichten uitvoert om aan te geven welke “horloges” zijn geactiveerd:

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


Antwoord 3, autoriteit 8%

$watchCollectionis geoptimaliseerd voor vector arrays []waar elementen kunnen worden gepusht

en $watchis goed voor associatieve arrays-objecten {}

$watchCollectionkijkt niet naar diepteveranderingen, is als kijken met objectEquality ingesteld op false.

Als u al weet hoe u de diepte moet structureren, kunt u deze als volgt optimaliseren:

 // 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
    }
  });

Other episodes