I've been battling with a large data array of varied length roughly between 100 ~ 200 items, but can be greater.
The data items themselves come from a custom reporting algorithm that produces the array of objects.
Object example:
ts:budget: "foo"
ts:category: "foo"
ts:client: "foo"
ts:entryTime: 14.5
ts:project: "foo (00000000)"
ts:task: "foo"
ts:user: "foo"
ts:userGroup: "foo"
Multiply that object example by 100 ~ 200 and that's what I'm working with. Nothing massive, so I wasn't expecting such a large performance hit. I very much suspect it's my factory code that's the issue, but I've gone through and optimised several areas (I.e. replacing angular.ForEach loops with native for loops) and have clawed back performance, but still hit a CPU usage of around 25% when the factory is called.
Factory code:
var report = '{"userID":"111868022517936189634", "jsonPayload":{"metrics":[{"ID":"ts:entryTime"}],"dimensions":[' + dimensions + '],"filters":[]}}';
var promise = $http.post("report.php?action=show&type=report&rangeStart=" + rangeStart + "&rangeEnd=" + rangeEnd, report).success(function(results) {
var uniqueArray = [];
for (m = array.length - 1; m >= 0; m--) {
var subItemUniqueArray = [];
if (uniqueArray.indexOf(array[m]) == -1) {
uniqueArray.push(array[m]);
for (k = uniqueRequireArray.length - 1; k >= 0; k--) {
uniqueRequireArray[k] == 'category' ? array[m]['categories'] = [] : array[m][uniqueRequireArray[k] + 's'] = [];
}
for (j = results.length - 1; j >= 0; j--) {
for (var x in results[j]) {
if (results[j].hasOwnProperty(x)) {
if (x == 'ts:' + type) {
var relationString = null;
type != 'project' ? relationString = array[m][relation] : relationString = array[m].name + ' (' + array[m].projectNumber +')';
if (results[j][x] == relationString) {
for (i = uniqueRequireArray.length - 1; i >= 0; i--) {
var obj = {
'item': results[j]['ts:' + uniqueRequireArray[i] + '']
}
if (subItemUniqueArray.indexOf(obj.item) == -1) {
uniqueRequireArray[i] == 'category' ? array[m]['categories'].push(obj) : array[m][uniqueRequireArray[i] + 's'].push(obj);
subItemUniqueArray.push(obj.item);
obj.entryTime = results[j]['ts:entryTime'];
if (uniqueRequireArray[i] == 'user') {obj.externalID = $userlookup.email(obj.item);} // add user externalID
if (uniqueRequireArray[i] == 'category') {obj.colour = $colourlookup.name(obj.item);} // add category colour
if (angular.isDefined(results[j]['ts:category'])) {
if (uniqueRequireArray[i] == 'budget') {obj.colour = $colourlookup.name(results[j]['ts:category']);} // add budget colour
if (uniqueRequireArray[i] == 'task') {obj.colour = $colourlookup.name(results[j]['ts:category']);} // add task colour
}
}
else {
obj.entryTime += results[j]['ts:entryTime'];
}
}
break;
}
}
}
}
}
}
}
}).error(function(data) {
$debug.admin('Service: Failed getting report results for overview', 'error', true);
}).then(function(results) {
return results;
});
return promise;
I doubt having 5 for loops is ideal for performance, especially as the very top for loop is driven by another array fed into the service that can be anywhere from 30 to 200 items in length.
Given roughly a minute, the function successfully creates the correct data bindings and populates the front-end repeater and CPU usage drops. Its just for that time, the app is completely unusable.
Any help will be massively appreciated!