When trying to render more than 120 items from an array (with images) the scrolling of the list becomes slower. Basically, when I am loading new data in infinite scroll, I am concatenating old array data with new array data.
On the other hand, popular websites like dribbble, behance dont seem to have this issue. Maybe this issue is specific to Angular.js? Has anyone faced this problem in their projects?
INFINITE SCROLLING IN ANGULARJS
No need of any additional plugins.
app = angular.module("demo", []);
app.controller("MainController", function($scope, $http){
// the array which represents the list
$scope.items = ["1. Scroll the list to load more"];
$scope.loading = true;
// this function fetches a random text and adds it to array
$scope.more = function(){
$http({
method: "GET",
url: "https://baconipsum.com/api/?type=all-meat¶s=2&start-with-lorem=1"
}).success(function(data, status, header, config){
// returned data contains an array of 2 sentences
for(line in data){
newItem = ($scope.items.length+1)+". "+data[line];
$scope.items.push(newItem);
}
$scope.loading = false;
});
};
// we call the function twice to populate the list
$scope.more();
});
// we create a simple directive to modify behavior of <ul>
app.directive("whenScrolled", function(){
return{
restrict: 'A',
link: function(scope, elem, attrs){
// we get a list of elements of size 1 and need the first element
raw = elem[0];
// we load more elements when scrolled past a limit
elem.bind("scroll", function(){
if(raw.scrollTop+raw.offsetHeight+5 >= raw.scrollHeight){
scope.loading = true;
// we can give any function which loads more elements into the list
scope.$apply(attrs.whenScrolled);
}
});
}
}
});
li{
display:block;
list-style-type:none;
margin-bottom: 1em;
}
ul{
height:250px;
background: #44E394;
color: #fff;
overflow:auto;
width:550px;
border-radius: 5px;
margin:0 auto;
padding: 0.5em;
border: 1px dashed #11BD6D;
&::-webkit-scrollbar{
width:8px;
background-color:transparent;
};
&::-webkit-scrollbar-thumb{
background-color:#b0fccd;
border-radius:10px;
}
&::-moz-scrollbar{
width:8px;
background-color:transparent;
};
&::-moz-scrollbar-thumb{
background-color:#b0fccd;
border-radius:10px;
}
&::-ms-scrollbar{
width:8px;
background-color:transparent;
};
&::-ms-scrollbar-thumb{
background-color:#b0fccd;
border-radius:10px;
}
}
body{
text-align:center;
font-size:1.2em;
font-family: "Helvetica";
color: #44E394;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAG0lEQVQIW2P88OHDfwY0wAgSFBAQYEQWp1AQAKUbE9XRpv7GAAAAAElFTkSuQmCC) repeat;
padding: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app='demo'>
<div data-ng-controller='MainController'>
<ul class='hello' when-scrolled='more()'>
<li data-ng-repeat='item in items'>
{{item}}
</li>
</ul>
<div data-ng-show='loading'>Loading</div>
</div>
</div>
<h1>INFINITE SCROLLING IN ANGULARJS</h1>
ngInfiniteScroll
is just a directive that you can use to implement infinite scrolling and it doesn't affect this problem.
here are some tips to speed up the app
Avoid using watchers in repeating section when ever you can
{{::model}}
ng-*
: all of them add a $watch.$watchCollection
or $watch
ng-if
instead of ng-show
: it removes dom and destroys watchers in.track by
: For large collections, this significantly improves rendering performance.In Concatenating:
you could see your problem in plunker and next command
[].push.apply($scope.list,getNewList());
is better than
$scope.list=$scope.list.concat(getNewList());
But all above tips lets user have more items in the list but when number of items in the list get more than (let say 1000) the scrolling becomes slow again
For this problem we could use Angular Material md-virtual-repeat which just load visible items on demand as i used in this your problem with virtual repeat.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With