I have a quite extensive filter/faceted search application. Data are loaded via an API, and then displayed on the page using a ng-repeat. There's also a google map instance which has a marker associated with every item. So the application is quite demanding in terms of computation. I guess I might be overloading some clients with weaker machines in the end.
That's enough of background. I have got it working the way I want. Now I'm looking for performance gains and more effective ways to accomplish my goals.
Now I'm trying to figure out whether it is better to update a $scope variable (which is an array) inside a forEach loop, or update a private array and then update the $scope variable after the loop?
So this
$scope.myArrayWithAllTheItems = [];
$scope.myArrayWithItemKeysToBeDisplayed = [];
$http({method: 'GET', url: '/MYAPIURL'}).success(function(data, status, headers, config) {
if (angular.isArray(data)) {
angular.forEach(data, function (item, key) {
/*
some prework on item object here
*/
//update scope variable with every forEach iteration
$scope.myArrayWithAllTheItems.push({
/*
BIG OBJECT WITH MY DATA
foo : bar,
etc...
*/
});
//I store keys of the items that will be displayed on the page at any one moment
//Changing filter controls will alter this array, not the big one containg all the data
$scope.myArrayWithItemKeysToBeDisplayed.push(key);
});
} else {
//display error...
}
}).error(function(data, status, headers, config) {
//display error...
});
versus this (I removed the comments and else branches, but otherwise the bit is identical except for 2 private arrays):
$scope.myArrayWithAllTheItems = [];
$scope.myArrayWithItemKeysToBeDisplayed = [];
$http({method: 'GET', url: '/MYAPIURL'}).success(function(data, status, headers, config) {
if (angular.isArray(data)) {
//private array variables to be update during the loop
var _myArrayWithAllTheItems = [],
_myArrayWithItemKeysToBeDisplayed =[];
angular.forEach(data, function (item, key) {
_myArrayWithAllTheItems.push({
});
_myArrayWithItemKeysToBeDisplayed.push(key);
});
//now update $scope variables only after the loop
$scope.myArrayWithAllTheItems = _myArrayWithAllTheItems;
$scope.myArrayWithItemKeysToBeDisplayed = _myArrayWithItemKeysToBeDisplayed;
}
});
It's exactly the same!
Changing a $scope variable will not immediately force a UI/DOM rendering. The actual render will only occur when angular's $digest()
is called.
So, unless you are forcing a $digest()
somewhere on your forEach stack, no render will occur until the end of the loop, making both options (basically) equivalent in terms of performance.
Check this explanation on how data binding works on AngularJS.