Quick Tip: Cross-platform TableView Lazy Loading

Futuristic technology background. Internet data connection. Cloud networks.

The concept of Lazy Loading refers to displaying only the data that is visible to the user and download more data as the user scrolls. This means that if you have a query that returns 200 rows, as a best practice, you should never load all 200 rows at once. Think of it as providing “paging” functionality without explicitly providing buttons to move to the next page. By implementing Lazy Loading, your data-driven apps will be more responsive and will provide a better user experience.

To implement Lazy Loading, you need to listen to the scroll event and keep track of where the TableView is at, and according to its position decide to load more data. It’s a pretty straight-forward approach, the tricky part is to implement it in a way that works on both iOS and Android.

On Android it’s fairly easy. Android provides three properties on the Scroll event: firstItemVisible (A), visibleItemCount (B) and totalItemCount (C). By applying a simple formula ( A+B=C ) we can know exactly when to trigger the “loadData” function.

On iOS however, we need to add additional variables to keep track of the TableView position. The iOS Scroll event gives us the contentOffset (A) object which contains the x,y coordinates of the part of the TableView that is currently visible to the user. We add the currentSize (B) variable to keep track of the total size of the TableView. We then add the overlap (C) variable to represent a bottom margin. This margin is used to trigger the loading of more data just as the user reaches the bottom of the TableView. Finally we keep a variable with the initialTableSize (D). With these values we build the formula (B-C < A+D) which will effectively trigger the right moment to load more data.

I’ve uploaded to Github a full sample App. Credit for the original concept of this code goes to César Cavazos – @cesarcvz.

Have fun!


  1. Hey ricardo – will you see a benefit to creating the rows ahead of time, but only appending them in loadData() as the user scrolls?

    • @meeech If you mean downloading the data all at once and then load from memory, I think it depends on how much data you’re dealing with. Certainly the Lazy Loading technique can be used for both limiting the amount of data tranferred as well as simply providing a friendly way of displaying it.


  2. @ricardo i meant having the table rows generated, but not table.setData all the rows at once, but to populate in groups of say 30.

  3. A few pointers on our road to lazy loading (before switching to ListView, which I agree, doesn’t implement a lot of functionalities yet):

    Scroll events are called a lot of times (as expected) when the user scrolls quickly through the list. If building a row is “expensive”, you get a build up in the events, thus causing a major performance issue.

    Our first stage solution was to minimize the scroll handler to just store the event, and add a “scrollend” handler which does the render. Worked fairly nice, but on old iPhones (3g,4) the amount of scroll events would still cause major performance issues. 🙁

    We had no choice, eventually, but to export TableView’s contentOffset native parameter to the javascript so to cancel the scroll event handler. (which was a bit surprising to me that wasn’t exported originally by Titanium).

    Hope this helps someone…

Comments are closed.