Yesterday I mentioned that wireless networks have high latency. I thought I’d expand on that and provide some statistics from a real world scenario.
High network latency means that it takes a long time for a packet to arrive at its destination. This is not a big deal when you’re downloading a large file or watching online video, because it just means that the start of the download is slightly delayed.
When communication goes back and forth and the other party has to wait for a packet to arrive before responding, that’s when high latency becomes a problem. This is particularly apparent when you open a new network connection to a server, because of the handshake packets between the client and the server.
Wireless networks are prefect examples of high latency networks. Therefore you need to consciously consider how to optimize data transfers in your iPhone/iPad apps. You should avoid multiple small server requests and instead try to do one large download that contains all the data in one request/response. Of course that may require changing the server API.
Here’s an example of why this may be worth your while:
A project I worked on recently needed to request URLs for image thumbnails for a large number of videos. The first – very naive – implementation looped through the video objects and requested each thumbnail URL. This resulted in 60 requests to the server, which took a total of 46 seconds over a wireless network. (Over a lower latency network the same number of requests took just 26 seconds. This illustrates the difference latency makes when you have many requests.) Of course waiting 46 seconds (or even 26 seconds) before the app is fully usable is not acceptable.
After a slight redesign, the app now creates an array of all the videos URIs and sends that to the server in one request. The response is an array of URLs. There are some other server requests that are necessary, so the total number of requests is now down to 8, a significant reduction from 60. And the total time to retrieve the same data is now reduced from 46 seconds to just 5.
It’s the same amount of payload data before and after the optimization. The performance difference is due to the overhead in creating network connections.
A performance improvement close to a factor of 10 is not bad for a few hours of coding.
October 19th, 2010 at 09:42
Could you not get similar speedups by simply running the requests asynchronously? If you send all 60 requests at once, the results should all come back at about the same time (assuming your server handle that many incoming requests).
October 20th, 2010 at 05:15
@Seth: The requests were actually asynchronous. (Although we were using a third party video SDK that may have had some queueing internally.) You should also be conscious of the limits of the iPhone. For example, if you have more than 5 mail accounts setup on your iPhone and then retrieve new mail, you will see how the entire UI locks up due the the multiple background communication threads.
October 19th, 2010 at 12:39
Grouping similar requests that are bound to happen anyway is definitely a good thing to do but it is even better to know the URL to your thumbnails instead of asking for them, i.e. having thumbnail URLs that can be berived from your video id or whatever. The downside is that you have to commit to your naming scheme in the future and cannot move resources around as easily. Given that the API you are talking to is yours to manage implementing such a scheme seems worth the 5 seconds.
October 20th, 2010 at 05:17
@Paul: In this particular case the video thumbnail URLs were generated on request and could not simply be requested by a naming scheme. We were using the Kyte video service and their iPhone SDK.
October 21st, 2010 at 07:02
Latency is a very big problem, thanks for sharing!