iOS优化网络性能(读书笔记)

来源:互联网 发布:织梦cms如何添加视频 编辑:程序博客网 时间:2024/06/05 20:23

降低请求带宽

降低带宽消耗的几种方式:

  • 使用高效的数据格式
  • 必要时使用预压缩数据(media)
  • 压缩请求负载和响应负载(text)

压缩响应

        压缩响应是一种简单的优化带宽的方法,只需要服务器很小的改变即可。

        response由headers和body组成。压缩响应是指利用算法将body压缩,而保留headers完好无损。JSON和XML格式的数据,可以被压缩到小于10%,压缩比例根据负载不同而不同,负载越大,压缩比就越大。

          iOS全部的HTTP NSURLConnection 请求都默认可以压缩,给

NSURLConnection请求添加如下HTTP header:

                      Accept-Encoding: gzip, deflate

告知服务器,客户端可以解压以gzip和DEFLATE格式压缩的响应负载,但是服务器可自行决定是否压缩负载。解压负载的运算开销要远远小于传送十倍以上的数据的开销,所以压缩响应还是很有好处的。如果需要不压缩响应,可以利用如下代码,清除这个header:
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:url                                                                 cachePolicy:NSURLCacheStorageAllowed                                                             timeoutInterval:20] autorelease];    [request addValue:@"" forHTTPHeaderField:@"Accept-Encoding"];

    压缩响应需要设置服务器,压缩响应负载。首先添加两个模块:

           LoadModule filter_module library-path/mod_filter.so

           LoadModule deflate_module library-path/mod_deflate.so

然后设置要压缩的内容,最简单的,设置全部数据利用DEFLATE压缩:

          SetOutputFilter DEFLATE

这种方式并不常用,因为它只对数据全部是text时,比较有效,如果数据时音频、图片等预压缩过的资源,占用CPU进行压缩,可是压缩后的资源size并不会有明显变小,划不来。一种更有效的方式是设置只压缩指定的、压缩后会明显减小size 的资源类型的资源,如下是压缩一些常见资源类型的代码:

          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


压缩请求

   压缩请求非常必要,因为广域无线传输速度通常是不对称的,从服务器发送至设备带宽大,而将数据从设备发送出去带宽小。这主要是因为大多数的网络流量通常是不对称的。如果应用程序不是这种标准的非对称模式,就应该认真考虑压缩请求。

    不同于压缩响应,压缩请求复杂很多,需要客户端和服务器端共同实现。

    首先,需要为服务器设置一个input filter,用于响应压缩的相同模块在Apache中同时执行请求压缩。下面的配置片段加载所需的模块。

         LoadModule filter_module library-path/mod_filter.so

         LoadModule deflate_module library-path/mod_deflate.so

        下一个步是定义一个input filter的DEFLATE模块。下面的代码片段定义了一个input filter和一个CGI别名:

        SetInputFilter DEFLATE

        SetOutputFilter DEFLATE

        ScriptAlias /cgi/ <html-directory>/cgi-bin/

       然后,在iOS APP中添加压缩代码,压缩请求分为两步,1.压缩负载,2.在请求中添加一个Content-Encoding header。压缩HTTP 请求body的代码如下,需要添加libz.dylib框架:
- (NSData *)compressNSData:(NSData *)myData {    NSMutableData *compressedData = [NSMutableData dataWithLength:16384];        z_stream compressionStream;        compressionStream.next_in=(Bytef *)[myData bytes];    compressionStream.avail_in = [myData length];    compressionStream.zalloc = Z_NULL;    compressionStream.zfree = Z_NULL;    compressionStream.opaque = Z_NULL;    compressionStream.total_out = 0;        if (deflateInit2(&compressionStream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) {        errorOccurred = YES;        return nil;    }    do {        if (compressionStream.total_out >= [compressedData length]) {            [compressedData increaseLengthBy:16386];        }                compressionStream.next_out = [compressedData mutableBytes] + compressionStream.total_out;        compressionStream.avail_out = [compressedData length] - compressionStream.total_out;                deflate(&compressionStream, Z_FINISH);            } while (compressionStream.avail_out == 0);    deflateEnd(&compressionStream);    [compressedData setLength: compressionStream.total_out];    return compressedData;}

        添加header代码如下,没有这个header,服务器模块不知道这个请求是压缩的。

[request addValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];NSData *compressed = [self compressNSData:myData];[request setHTTPBody:compressed];reqSize = [compressed length];

减少请求延迟
        
        iOS设备上,不可以减少一个HTTP请求的延迟时间,但是可以减少发布多个HTTP请求的延迟时间。减少请求延迟时间可以:在单个TCP连接上集中处理HTTP请求,流水线操作HTTP请求以优化使用全双工TCP连接。
    1.HTTP请求聚类,这种是默认方法。一个程序使用完NSURLConnection对象后,在关闭连接前保持几秒打开状态,这样可以省去不必要的更新,直到需要更新数积累到一定程度,或者用户一些操作使得网络活跃。这种方法可以保持一个连接,避免建立多个TCP连接的开销。
    2.为服务层建立一个单一的服务端点,通过重用一个连接来减少延迟。
    3.HTTP流水线是第三种重用现有TCP连接的方式。它使HTTP客户端在第一次请求返回响应之前用同一个TCP套接字发送第二个请求。返回的响应的顺序和发送请求的顺序一致。POST和PUT会修改服务器上的实体,所以不建议流水线操作发送POST和PUT请求。
使用流水线操作代码如下:
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]                                    initWithURL:[NSURL URLWithString:url]];    [request setHTTPShouldUsePipelining:YES];

0 0
原创粉丝点击