Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Network-Efficient Apps

Building Network-Efficient Apps

Architecting a mobile app that uses the network requires that we think about things differently than when we build software on the server. This presentation covers six main topics that can help you design apps that use the network more efficiently, resulting in a more pleasant user experience.

Steve Madsen

October 25, 2013
Tweet

More Decks by Steve Madsen

Other Decks in Programming

Transcript

  1. Designing for the Network • Security • Topology • Latency

    • Bandwidth and CPU time • Power • Timeouts
  2. Designing for the Network Balance You can’t apply all of

    the advice in this talk to a single app. Some things are diametrical: conserving bandwidth and pre-fetching content, for example. Consider everything and then decide what makes the most sense for your app in service to its users.
  3. Security • Use SSL/TLS • Never disable certificate chain validation

    • Consider shipping your server certificate (“SSL Pinning”) to verify it It’s easy to sniff and compromise public Wi-Fi. It’s easy to impersonate an SSL server if the client doesn’t validate the certificate chain. You don’t know the value your user places on the data they create with your app. SSL Pinning provides the strongest security, but then your app needs to handle certificate expiration.
  4. Topology Topology is the how the network is built: how

    packets get from device to server and the characteristics of the network along each hop. For an app developer, though, it’s mostly about the perceived performance of the network.
  5. Topology ≠ Wi-Fi at home does not perform the same

    as Wi-Fi on a plane, but to your device, they’re both Wi-Fi. For apps where it matters, adapt to observed conditions. This is what HTTP Live Streaming does: it adjusts the bitrate based on if it’s falling behind or easily keeping up. Most apps don’t need to do anything about this, but it greatly affects the perceived performance and quality of those that do.
  6. Simulating Topologies The Network Link Conditioner is part of the

    Hardware I/O Tools for Xcode download, available at developer.apple.com/downloads. With it, we can test in an environment closer to real world conditions without leaving our desks. It’s also built into iOS 6+. Another option is running an HTTP proxy (e.g., Charles Proxy) that can throttle on your desktop and routing traffic from the device through that.
  7. Latency Two ways to think about latency: 1. From a

    low-level network point of view (i.e., round-trip time) 2. From the user’s point of view (i.e., how long it takes to do something)
  8. Latency Wi-Fi LTE “4G” HSPA+ 3G 50-75 ms 120-150 ms

    130-195 ms 110-145 ms Cellular latency hasn’t improved much from the 3G days, and it varies significantly based on congestion and signal strength.
  9. Connection Timeline Server Client SYN SYN+ACK ACK 0 ms 150

    ms GET /resource.json 300 ms ACK response HTTP runs on TCP, and TCP’s three-way handshake to establish a connection imposes significant overhead on high latency links. Here, a hypothetical 150 ms round-trip time means it’ll be close to 300 ms after initiating a request before you can expect to get any data back from the server.
  10. Cellular Connection Timeline Server Client SYN SYN+ACK ACK 0 ms

    1150 ms GET /resource.json 1300 ms ACK response Cellular radio powers up 1000 ms Making matters worse, if your device is off of Wi-Fi and the cellular radio is idle, the transition to the high power state where transmission can actually take place takes a full second. Now the overhead to establish an HTTP connection is close to 1.5 seconds before the device sees the first byte of the response.
  11. Average fetch time per record 1 record/request, 100 API requests,

    new connection 363 ms Simulated LTE: 20 Mbps down, 5 Mbps up, 150 ms ping A naive implementation to fetch a set of records from a web service with a mis-configured server might require a brand new HTTP connection (and its TCP overhead) for every record. This will be very slow.
  12. Connection Timeline Server Client SYN SYN+ACK ACK GET /resource.json ACK

    response FIN ACK FIN ACK TCP also has overhead associated with closing a connection. Each side must send the other a FIN packet, plus a final ACK of the other side’s FIN.
  13. Request Timeline Request Response Connection 1 Connection 2 Connection 3

    Overhead Net effect: multiple serial requests are dominated by TCP overhead, not by transmitting the request or response.
  14. Average fetch time per record 1 record/request, 100 API requests,

    new connection 1 record/request, 100 API requests, keep-alive enabled 363 ms 70 ms Simulated LTE: 20 Mbps down, 5 Mbps up, 150 ms ping Fixing that mis-configured server by allowing HTTP keep-alives significantly improves the latency. Now clients have the option to re-use an existing TCP connection to make the next HTTP request.
  15. Request Timeline Keep-Alive Connection Request Response Connection 1 Connection 2

    Connection 3 Overhead An illustration of HTTP keep-alive. One connection, back-to-back request and responses.
  16. Average fetch time per record 1 record/request, 100 API requests,

    new connection 1 record/request, 100 API requests, keep-alive enabled 1 record/request, 100 API requests, pipelined 363 ms 70 ms 18 ms Simulated LTE: 20 Mbps down, 5 Mbps up, 150 ms ping HTTP/1.1 conforming web servers are required to support pipelining, which further improves the situation by allowing the client to send multiple requests to the server without waiting for previous responses.
  17. Request Timeline Keep-Alive Connection Request Response Connection 1 Connection 2

    Connection 3 Pipelined Connection Overhead HTTP requests tend to be small compared to responses. This diagram isn’t drawn to the same scale as the numbers from my test. The larger responses are compared to requests, the more pipelining helps. I’m told that no Android client libraries support pipelining because of problems with some HTTP proxies. If true, iOS clients would likely have problems, too. Using SSL should solve this problem, because SSL effectively gives the client a tunnel directly to the server. (Proxies can’t do the same thing as for regular HTTP, because their SSL certificate wouldn’t pass chain validation.)
  18. Average fetch time per record 1 record/request, 100 API requests,

    new connection 1 record/request, 100 API requests, keep-alive enabled 1 record/request, 100 API requests, pipelined 100 records in 1 API request 363 ms 70 ms 18 ms 4 ms Simulated LTE: 20 Mbps down, 5 Mbps up, 150 ms ping Finally, if you have control over the API and fetching multiple records is an operation your client often performs, consider adding an endpoint to fetch multiple records in one request.
  19. The other way to look at latency is from the

    user’s perspective: how long does it take to complete a task? In Instagram, tapping “next” starts uploading the photo while the user is entering a caption and other information on the share screen. From their perspective, posting is very fast because Instagram hides the high latency work (uploading the photo) in the background. The only thing left to post after tapping “share” is some metadata.
  20. Hide Latency • Combine resource fetches when the API allows

    • Use HTTP keep-alive and pipelining • Pre-fetch resources • Upload in the background Both iOS and Android provide API to let the system wake up your app when it’s a good time to use the network, and to detect when the device is plugged in and on Wi-Fi.
  21. Power Source: A. Carroll, G. Heiser, “An Analysis of Power

    Consumption in a Smartphone” CPU 48mW Wi-Fi 55mW GPS 143mW Backlight @ 67% 140mW GSM 210mW Numbers are from an Openmoko Neo Freerunner, which is, admittedly, an older device, but the breakdown likely hasn’t changed significantly. The cellular radio is the most power-hungry component in a mobile phone unless the display is set to a high brightness.
  22. Power • Cellular radio stays at high-power (~ 1 W)

    mode for 4 seconds after last transmission • Next 15 seconds, drops to approximately ½ of high-power (~ 0.5 W) • LTE is not much different • NSURLSession discretionary (iOS) or SyncAdapter (Android) Source: B. Zhao, Q. Zheng and G. Cao, “Energy-Aware Web Browsing in 3G Based Smartphones” Be bursty: once you pay the cost of powering up the radio, do as much work as you can, then stay idle for as long as possible.
  23. Bandwidth & CPU Size Size (deflate) Parse Time XML JSON

    15 KB 3.2 KB 36.0 ms 8 KB 3.0 KB 23.5 ms 100 element array. XML representation generated by Rails 3. XML parsed by NSXMLParser, JSON by NSJSONSerialization, plists by Foundation. Times from iPod touch (4th gen). Very simple data structure with two random strings and an integer. There is no DOM parser built-in to iOS or Android. You have to use a more verbose SAX parser (with callbacks). I consider JSON to be best in class: compact and readable format, very compressible, excellent server-side support and a fast, easy to use, built-in parser on iOS 5. Android has a JSON parser, too, though most people use a third-party library.
  24. Bandwidth & CPU Keep in mind that most people are

    on bandwidth-capped plans, and using too much data can cost them money. Balance your use of bandwidth for data they explicitly request or are likely to need.
  25. Timeouts As app developers, we can’t even try to judge

    what our users think is important. They’re trained after years of browser use anyway: what happens when a page is slow to load? We refresh. So let the same thing happen in your apps. Long timeouts, let the user decide when to cancel and retry.