Reputation: 43491
I have a page that needs to load thousands of rows from an API (via an AngularJS service). Rather than do it all at once, I decided to load in 100 at a time, ala:
$scope.fetchTransactions = function(page) {
TransactionService.get($scope.product, page).then(function(response) {
$scope.transactions = $scope.transactions.concat(response.data.transactions);
if(response.data.transactions.length > 0) {
$timeout(function() {
$scope.fetchTransactions(page + 1);
}, 1000);
}
});
}
$scope.fetchTransactions(1);
This loads 100 transactions at a time. In my view, I have a table and a tr
that looks like:
<tr class="fade-in-repeat" ng-repeat="transaction in transactions | orderBy: ['-txid', '-time']>
When it loads, the browser freezes for a second here and there. What can I do to speed that up?
** SAMPLE JSON for one transaction **
{
"__v":1,
"_id":"52e7c99dc22c6f16aee227e7",
"blockhash":"00000000186a147b91a88d37360cf3a525ec5f61c1101cc42da3b67fcdd5b5f8",
"blockheight":51741,
"blockorder":601,
"blocktime":1271619803,
"locktime":0,
"time":1271619803,
"txid":"0a37858c0d00af40cce12256133d7e743c42ffb345e8826d3e6700c6d0745413",
"version":1,
"vin_total":27.34,
"vout_total":27.34,
"updatedOn":"2014-01-28T15:15:41.508Z",
"indexedOn":"2014-01-28T15:15:41.508Z",
"vout_addresses":[
"1CQXTdQYwquztA6jry2NjDVfRoizPco5rR",
"1XPTgDRhN8RFnzniWCddobD9iKZatrvH4"
],
"vout":[
{
"n":0,
"spent_txid":"60417dc3a354910719c32eb3e70f14f971807cbb3a3c6b0b1cccc7b09c838115",
"value":27.33,
"scriptPubKey":{
"reqSigs":1,
"type":"pubkeyhash",
"addresses":[
"1CQXTdQYwquztA6jry2NjDVfRoizPco5rR"
]
}
},
{
"n":1,
"spent_txid":"77036fa2ac75212be1ce93e8e1008d5cb2bcbb51aa560a5fe29c9c1423bbd00e",
"value":0.01,
"scriptPubKey":{
"reqSigs":1,
"type":"pubkeyhash",
"addresses":[
"1XPTgDRhN8RFnzniWCddobD9iKZatrvH4"
]
}
}
],
"vin":[
{
"_id":"52e7c99dc22c6f16aee227e8",
"sequence":4294967295,
"txid":"c0eea97dc593f059f90630839557a5df1c3c8d7b73e01e5c8c01b89764705583",
"vout":1,
"meta":{
"address":"13QaytjPv9cAJbDjGZCKCthxd8kHtSWKHE",
"amount":27.34
}
}
]
}
Upvotes: 2
Views: 475
Reputation: 6187
In angular when you work with thousands of rows using ng-repeat
is a bad idea since it adds $watch to each element and as a result has a direct impact on performance.
so for now the best thing you could do is to work with the DOM your self, I would suggest creating your own directive and iterate the elements using the native JavaScript API or JQuery, it doesn't matter, also i would suggest using CreateDocumentFragment for DOM manipulations (why would you want to use CreateDocumentFragment).
Example:
mainApp.directive("myRepeater", function () {
var LIST_ITEM = "li";
return {
restrict: "A",
link: function (scope, element, attrs) {
var rawElm = element[0];
scope.$watch(attrs.source, function(newValue) {
if (!newValue || !newValue.length || newValue.length === 0) return;
// wipe the previous list
rawElm.innerHTML = "";
var frag = document.createDocumentFragment();
newValue.forEach(function (item) {
var listItemNd = document.createElement(LIST_ITEM);
var textNd = document.createTextNode("your text");
listItemNd.appendChild(textNd);
frag.appendChild(listItemNd);
});
rawElm.appendChild(frag);
});
}
};
});
Upvotes: 2
Reputation: 32357
$filter
):$scope.fetchTransactions = function(page) {
TransactionService.get($scope.product, page).then(function(response) {
if(response.data.transactions.length > 0) {
var transactions = $scope.transactions.concat(response.data.transactions);
$scope.transactions = $filter('orderBy')(transactions, ['-txid', '-time']);
$timeout(function() {
$scope.fetchTransactions(page + 1);
}, 1000);
}
});
}
track by
:<tr class="fade-in-repeat"
ng-repeat="transaction in transactions track by transaction ._id">
Upvotes: 0