views:

55

answers:

1

I have a mobile app, which is pretty data driven, though only through text and images. In the current version each click or touch requires pulling new data from the server (appache/php). With network delay this easily takes 1-2 seconds for the first content to appear, which is far too long.

I have heard about and considered the following options, but are not sure if some of them might be counter productive, or if I have left something important out?

  • Download all data from the start, in a big bunch with a loading screen?
  • Run a prefetching thread, predicting and downloading data the user might want, in the background?
  • Keep the connection open to the server at all time?
  • Load different parts of the data in different connections in parallel? (Similar to facebook)
  • Use heavy data compression?

A comprehensive article on the matter would also be a good answer.

+4  A: 

I would say that most of those suggestions are ... pretty average. Except for using compression. Definitely enable compression on the web server that you are using. You definitely do not want to keep a connection open or have multiple connections. The biggest problem for mobile devices is latency, rather than bandwidth, so using multiple connections won't help, but will drain the battery quickly. As for keeping the connection open, don't even think about doing that. That is one of the biggest postulates of mobile development - only keep a connection open when you need it.

The rule of thumb for mobile thin clients is to download the least amount of data possible when it's absolutely necessary. Here are a few tips:

  • Do not send much metadata with your data. In case of JSON, think about changing the structure so that you are not sending the field names for every record. Take the below JSON for example:
{
 success: true,
 data:[
   {ProductName: "Coca-Cola can", Weight: 380, imageUrl: "http://path.to/image.png"},
   {ProductName: "Gillete deodarant", Weight: 500, imageUrl: "http://path.to/image.png"}
 ]
}

As you can see there are a lot of duplicated field names, you can get rid of those to reduce the payload like so:

{
 success: true,
 fields: {"ProductName": 0, "Weight" : 1, "imageUrl": 2}
 data:[
   ["Coca-Cola can", 380, "http://path.to/image.png"],
   ["Gillete deodarant", 500, "http://path.to/image.png"]
 ]
}
  • Reduce the amount of data that gets sent each time. Don't send enough data for 10 screens at once. Provide maybe two or three screens worth and use infinite scrolling or some sort of paging.

  • Investigate HTTP caching. Make sure the caching headers are set and make sure that the webclient you are using respects those headers.

  • Cache aggressively. Have a look at any twitter client for iPhone/Android. They don't download the whole lot of visible tweets every time they start up, they are stored locally.

Igor Zevaka
Thanks for the great answer! Can I ask you why keeping the connection open is bad, if "The biggest problem for mobile devices is latency, rather than bandwidth"? I'd also love to dive into the twitter-droid code. I'll see if I can find it somewhere.
Thomas Ahle
Because open connections drain the battery very rapidly. No matter how many connections you open, you still going to get latency issues.
Igor Zevaka
I should really say both bandwidth and latency are an issue, so one connection can easily saturate the available bandwidth. The SDK might not even let you open simultaneous connections to the same server.
Igor Zevaka
Right, I see the point about simultaneous connections. Now I was just thinking about one single open connection, so I wouldn't have to send http requests for every user action.
Thomas Ahle
You definitely don't want to do that. An open connection drains the battery dramatically. If you don't need a connection, even for 10 seconds, close it. Otherwise you end up with a battery hungry app and lots of unhappy users.
Igor Zevaka
I see. So I do a HttpClient with timeout of 5-10secs and cache+gzip turned on, and let the server handle the rest. I'm still looking into more lazy download and sprite patterns and I guess most importantly some precise and nonobstructive way to give feedback in case of delay. Reducing raw datasize will also be in the looking glass. Thanks a bunch.
Thomas Ahle
I suggest allowing only one connection at a time and closing it after each chunk of data. Don't try jugging multiple concurrent connections; there's little benefit and it induces complexity.
seand