reduce the amount of bandwidth consumed by an app:
- Use an efficient data interchange format — Select an efficient encoding for data between the client and server. Chapter 4, “Generating and Digesting Payloads,” addresses the decision criteria for selecting the right payload format.
- Use precompressed data where possible — Compress or scale media assets such as audio, video, and images with special purpose algorithms to suit the channel and device.
- Compress each request or response payload — Compress text payloads to provide significant bandwidth savings with little impact on server or client code.
You can actually enable payload compression for nonmedia payloads by compressing server responses or client requests. The method for You can actually enable payload compression for nonmedia payloads by compressing server responses or client requests. The method for compressing a response is significantly different from compressing a request.
Response Compression
Response payload compression is the easiest form of HTTP payload compression to implement. An HTTP response is composed of the headers and body returned to the client in response to a previous HTTP request. Response compression applies a data compression algorithm to the response body and leaves the HTTP headers intact.
Response compression of text data can have a dramatic impact on the size of the data returned to the client. With JSON or XML (see Chapter 4 for details on creating and processing JSON and XML responses) the compressed payload can be less than 10 percent the size of the original payload, but your results may vary depending on the succinctness of the original payload. If the original source uses JSON with one-character field names and has all whitespace removed, you see more limited results compared to XML formatted for printing with lengthy element names. Typically, the larger the payload the greater the compression ratio. Some small payloads may experience a net increase in size due to compression lookup tables.
In iOS HTTP payload, compression is enabled by default for all HTTP NSURLConnection requests. The received payload is automatically decompressed and presented to your code in its original format. The computational overhead of decompression is substantially less than the communication overhead of transmitting ten times as many bytes; therefore, activating response compression is almost always beneficial.
NSURLConnection adds the following HTTP header to every request by default:
Accept-Encoding: gzip, deflate
The Accept-Encoding header informs the server that the client will accept payloads compressed with either gzip or DEFLATE compression, but it is the server’s choice whether to compress its response. Thus, the key to enabling the performance wins with response payload compression is to configure the server terminating the HTTP to support compression.
For example, the process to configure the Apache web server involves loading a compression module and activating an output filter for specific document types. First, your Apache configuration needs to load two modules.
LoadModule filter_module library-path/mod_filter.so
LoadModule deflate_module library-path/mod_deflate.so
The filter_module is a common module and is probably already loaded. The deflate_module is less common but is part of the standard Apache installation for Linux, OS X, and Windows.
Next you must define the content to compress. The brute force approach is to add an output filter applied to all content. The following snippet applies a global DEFLATE output filter:
SetOutputFilter DEFLATE
This is not a recommended approach unless you know that the web server is serving only text data that can benefit from compression. Applying compression to precompressed content, such as images, audio, and video, can consume CPU resources to perform the compression while having little to no positive impact on the size of the payload. A more targeted approach is to add output filters for only the content types that can benefit from compression. The following code applies compression to several common content types:
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/json
Enabling response compression should be transparent to other applications and browser-based users because the client software, either application or browser, must explicitly indicate that it accepts a compress payload with the Accept-Encoding header, which most modern browsers do. The only downside of compression is that it makes the payload difficult to read and debug when using a network sniffer to analyze traffic during development. A recommended approach is to enable compression in the test environments but not in development environments.
Many other HTTP servers, including Microsoft’s IIS, support response compression. For information on enabling compression in IIS see: http://www.iis.net/ConfigReference/system.webServer/httpCompression. Many load balancer appliances, such as BIG-IP appliances, support HTTP compression augmented by hardware-based compression subsystems.
If you do find a reason to disable payload compression, the app can prevent it by clearing the automatically set Accept-Encoding header. The following code is an example of clearing this header.
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc]
initWithURL:url
cachePolicy:NSURLCacheStorageAllowed
timeoutInterval:20] autorelease];
[request addValue:@"" forHTTPHeaderField:@"Accept-Encoding"];
The response to the request cannot be compressed by the server. Response compression is an easy way to optimize your application’s use of network bandwidth and requires only minimal changes to the service tier.