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?
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?
Share Improve this question asked Feb 8, 2017 at 5:36 shrbishtshrbisht 6763 gold badges9 silver badges25 bronze badges 15 | Show 10 more comments3 Answers
Reset to default 10 +50INFINITE 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
- Use one time bindings :
{{::model}}
- Decrease using
ng-*
: all of them add a $watch. - Decrease using
$watchCollection
or$watch
- Use
ng-if
instead ofng-show
: it removes dom and destroys watchers in. - Use
track by
: For large collections, this significantly improves rendering performance.
- Use one time bindings :
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.
I think you should think about optimize your application, not just select a better directive or plugins, Too many scopes can also slow the application.
ng-repeat
but withouttrack by
. See if you are missing that – tanmay Commented Feb 8, 2017 at 5:53