Ionic List Performance

I have a really small app code-wise, which displays an item list (each item has several nested properties) that I can filter with a search field. Initially I load 20 items from an API. Once the user reaches the end of the list, he can click on “load more” to load another 20 items. After the items are retrieved they are stored in LocalStorage to avoid too many API calls (caching). The list can grow pretty quickly (if using infinite scroll even faster) and you can really feel the UI getting less and less responsive.

Here are my performance observations. It shows the CPU usage spike while scrolling the list component. And by scrolling I mean quickly flipping through the list. As the list grows faster, people tend to scroll faster back and forth as well. I’ve run this with iOS 7 on iPhone 5:

20 items, CPU 30%
40 items, CPU 40%
60 items, CPU 45%
80 items, CPU 50%
100 items, CPU 60%

Of course these measurements are not really scientifically accurate, but I guess it is a good indicator. Once the CPU reaches 100%, it’s no more joy for the user. UI is really sloppy, hangs, and you start to tab things multiple times because they don’t respond.

I’m sure that there are such limitations which probably will never be as good as it can get with a native app.

I’m interested in ideas on how to improve this. Maybe using a less complex items list (flat, just the properties which are shown in the list - but then you would lose part of the search functionality), removing items which are not currently visible in the scroll view and replacing them by placeholders, generally truncating the list on resume, suspend, some kind of timeout…?

I’m really curious about your ideas!

2 Likes

Seens lots of discussion on this topic. Here are the best conversations I’ve seen:

http://tech.small-improvements.com/2013/09/10/angularjs-performance-with-large-lists/

On very long lists, you may actually want to change out the data that is inside the list. No point in rendering the top 500 rows if you are on the 1500th record in the view.

bindonce really made a difference, thank you @Calendee!

1 Like

Yes, thanks for sharing the link, @Calendee!

I should note as well we have a virtual list feature on the roadmap where we will only render the viewable subset of items.

9 Likes

Oooh, that would be really nice.

Could help too https://github.com/allaud/quick-ng-repeat

2 Likes

I can’t wait to see that one as well as the feature of doing a faster ng-repeat

Yep! Andy is hard at work on this one, track progress here: https://github.com/driftyco/ionic/pull/1157

2 Likes

I’ve created a directive for each row which does not have a scope, this seems to do the job alongside bindonce.

I’m afraid the only way is to give up with ionic for a while if your target is users with mid-low range of smartphones… I’ve tried many ways to speed up a list of only 500 items and I call it “only” because for me, with my background dated in 8-bit world, displaying 500 items on a hardware with 0,5 gb of ram and 700 mhz cpu should be a piece of cake, but it is but not with ionic :confused: First I used ng-repeat and the result was a total disaster. Then I’ve tried bindonce, own virtual scroll implementations, overflow-scroll, etc. Nothing helped much. Finally I’ve found the collection-repeat solution and this works somehow, but definately app is not responsive and lags. Then I’ve read here on the forum about the crosswalk, but 25 MB of additonal download size isn’t a good idea for a small app like mine. I’ve thought that the only way to have a fast app is to go native way. I was however curious how other phonegap/cordova apps handle lists so I’ve started to download such apps. I realized that their lists are faster and responsive with the feeling of native lists, even clicking on buttons around views feels better. How is this possible? The answer is different framework. So I’ve tried to rewrite the base features of my app to the onsenui from ionic and I couldn’t believe how fast is the list just from the start. No tricks, no “bindonces”, virtual scrolling, etc… Just simple ng-repeat + two filters + some ng-models and the list, even twice bigger (1000 items) than original is smooth like hell. You guys should definately look into this UI or just look on the Batarang’s dependencies tab or $watchCollectionWatch performance tab in your app to find something that will help people without the newest iphones use your UI. I hope that I will be able to use the ionic again in the future, but it must be much faster than now.

2 Likes

I didn’t give up and after checking all other things I’ve finally done what I should at the very beginning. I’ve removed the “item” class name from the li tag. Instead of the code from Components Guide:

<ul class="list">
    <li class="item">
      ...
    </li>
</ul>

I started to use:

<ul class="mylist">
    <li class="myitem">
      ...
    </li>
</ul>

and you know what? My app started to be responsive again. A simple list with 500 items and slow ng-repeat is now the same speed as the forementioned Onsen list and even faster and feels better than your collection repeat solution. I think there’s something wrong with the code in ionic.js that handles lists, but I’m more than happy that I can stay with ionics :smile:

2 Likes

Wait! What did you do? Removing the class item makes your list more slick?
Does your new class myItem has CSS properties like box-shadow set? And when you used collection-repeat did your list items stopped responding to click events occasionally?

hi what are the css codes for your myList and myItem classes? Would you mind sharing them to us?

There’s nothing special about them except that ionic isn’t touching them when operating on DOM, I think…

.my-content {
	width: 100%;
	height: 100%;
	overflow-y: scroll;
}

.my-list {
	list-style: none;
	font-size: 25px;
	line-height: 62px;
}

.my-item, .my-item-divider {
	height: 62px;
	border-bottom: 1px solid #ddd;
	padding-left: 15px;
	width: 100%;
}

.my-item-divider {
	background-color: #eee;
}

As you can see there’s no magic except that I’ve removed ion-content, ion-list and ion-items from my templates and everything started to be acceptable in use on “old” Android 4.x (below 4.4). Otherwise unusable.

Another funny thing is that I’ve tried to use the tabbed template recently. Just set up an app with ionic start but gave up quickly and didn’t waste more time. Same about slide box. Animations are choppy and unusable giving a very bad feeling about the developer who wants to publish such an app. Changed everything to custom tabs solution + animations from animate.css (google if needed more info) and wow! This is how all this should work from scratch. I know ionic is in beta phase and I really hope it will grow up till the final 1.x because I like the idea of custom tags for all these components it offers.

3 Likes

Just want to say that your advice has worked. I too was having problems with list item scroll performance with 200+ lists( no images) even when I implemented custom infinite scrolling. using a custom class instead of .item( i removed using component) and it greatly improved performance ten-fold

just wanted to say that i probably spoke too soon. i’m still getting some crashing on iOS 4

@Calendee

this performance tuning suggested in tech.-samll-impromentes or bidonce are implemented in ionic now?
or i still need do things like that?

smalls list’s are running smooth there and i need for Iphone4s and android 4.0+ phones

this problem with long lists is solved or still there?

If you’re not using the new collection repeat feature, then you do need those performance improvements. However, that’s pretty outdated now. You don’t need bind-once anymore because Angular has that built-in “one-time binding”, but you must implement it.

Docs : https://docs.angularjs.org/guide/expression (See One-time binding)

Examples : http://swirlycheetah.com/native-bind-once-in-angularjs-1-3/

still there

http://kendallarneaud.me/mobile/android/AATT/version/0.0.2.3/

anybody has any more suggestions?