网络性能优化

网络性能优化

0x01 典型的网络操作流程:

手机端发起网络请求 <-> 到达网络服务运营商的基站 <-> 转移到服务提供者的服务器上进行解码 <-> 访问本地存储数据库 <-> 进行编码,按照原来的路径逐层返回

networkbehavior.png

在上面的网络请求链路中任何一个环节都有可能导致严重的延迟,成为性能瓶颈,但是这些环节可能出现的问题,客户端应用是无法进行调节控制的,应用能够做的就只是根据当前的网络环境选择当下最佳的策略来降低出现网络延迟的概率。

主要的实施步骤有两步:

  1. 检测收集当前的网络环境信息

    根据当前网络速率来调整网络请求的行为

networkspeed.png
  1. 根据当前收集到的信息进行网络请求行为的调整

    例如把网络延迟分为三档:GOOD、OK、BAD。

    如果网络延迟属于GOOD的范畴,我们就可以做更多比较激进的预取数据的操作。

    如果网络延迟属于BAD的范畴,我们就应该考虑把当下的网络请求操作Hold住等待网络状况恢复到GOOD的状态再进行处理。

    前面提到说60ms,220ms是需要提前自己预测的,可是预测的工作相当复杂。首先针对不同的机器与网络环境,网络延迟的三档阈值都不太一样,出现的概率也不尽相同,我们会需要针对这些不同的用户与设备选择不同的阈值进行差异化处理。

    Android官方为了帮助我们设计自己的网络请求策略,为我们提供了模拟器的网络流量控制功能来对实际环境进行模拟测量,或者还可以使用AT&T提供的 Network Attenuator来帮助预估网络延迟。

networkdelay.png

0x02 发生网络行为的三种类型

  • 用户主动触发请求
  • 被动接收服务器返回的数据
  • 数据上报,行为上报,位置更新等自定义的后台操作

0x03 网络请求场景

  • Using URL,普通的 HTTP 请求
BitmapFactory.decodeStream((InputStream)new URL(pathToImage).getContent());
  • Using HTTP,打开某个 URL 获取数据
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);

0x04 何时发起网络请求

  1. 区分网络请求,及时 / 延迟

  2. 避免使用 Polling 轮训的方式执行网络请求,Android 官方推荐使用 Google Cloud Messaging (中国不可用),这个框架会帮助把更新的数据推给客户端。

  3. 对可延迟的网络请求行为采取策略

    • 回退机制避免固定频繁的同步请求,例如,在发现返回数据相同的情况下,推迟下次请求时间
    backoff.png
    • Batch & Delay,使用 Job Scheduler,批处理的方式避免频繁的间隔请求,Google Play Service 提供了 GCMNetworkManager (中国不可用)帮助我们实现该功能。实现原理即:先将网络请求暂存到一个 PendingQueue 里面,等条件合适再出发 Queue 里面的网络请求。
batchdelay.png
* Prefetching,预取技术,提前把一些数据拿到,避免后面频繁再次发起网络请求。同样 `GCMNetworkManager` 能帮助我们实现该功能。
prefetching.png
* 等到网络切换到 WiFi 或者处于充电的时候执行

有效的 Prefetching 是一个问题,预取数据量偏少,起不到频繁请求作用;请求数据过多,就会造成资源的浪费。所以,1. 在 WiFi / 4G / 3G 等不同的网络环境下设计不同的预取数据量。2. 按照图片的数量或者操作时间作为阈值。3. 根据特定的场景设计合适的方案。同理设计 Batching 确定合适的条件触发也需要考量。

0x05 如何传递网络数据

不同的网络环境,下载速度以及网络延迟存在差异。

更低的网络环境 -> 执行更长的时间 -> 更长的网络操作行为 -> 消耗更多的电量。

未经过压缩的数据、更多的网络传输量,使得用户付出更多的流量费

  • 数据压缩

    在上传与下载数据之前,使用CPU对数据进行压缩与解压,可以很大程度上减少网络传输的时间。

    CompressorHead:这系列的课程会介绍压缩的基本概念以及一些常见的压缩算法知识。

    Image Compression:介绍关于图片的压缩知识。

    Texture Wranglin:介绍了游戏开发相关的知识。

    Grabby:介绍了游戏开发相关的知识。

    Gzip is not enough

    Text Compression

    FlatBuffers

  • 网络传输数据量量

    通常来说,网络传输数据量的大小主要由两部分组成:图片与序列化的数据

    • 减少图片大小

      PNG,JPEG,WEBP三种主流格式在占用空间与图片质量之间的对比

picturecompare.png
* 减少序列化数据大小
    
    JSON与XML为了提高可读性,在文件中加入了大量的符号,空格等等字符,而这些字符对于程序来说是没有任何意义的。        
    我们应该使用Protocal Buffers,Nano-Proto-Buffers,FlatBuffer来减小序列化的数据的大小。

0x06 缓存

想要使得Android系统上的网络访问操作更加的高效就必须做好网络数据的缓存。这是提高网络访问性能最基础的步骤之一。从手机的缓存中直接读取数据肯定比从网络上获取数据要更加的便捷高效,特别是对于那些会被频繁访问到的数据,需要把这些数据缓存到设备上,以便更加快速的进行访问。

Android系统上关于网络请求的Http Response Cache是默认关闭的,这样会导致每次即使请求的数据内容是一样的也会需要重复被调用执行,效率低下。通过以下代码开始 HttpResponseCache。

   protected void onCreate(Bundle savedInstanceState) {
       ...

       try {
           File httpCacheDir = new File(context.getCacheDir(), "http");
           long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
           HttpResponseCache.install(httpCacheDir, httpCacheSize);
       } catch (IOException e) {
           Log.i(TAG, "HTTP response cache installation failed:" + e);
       }
   }

   protected void onStop() {
       ...

       HttpResponseCache cache = HttpResponseCache.getInstalled();
       if (cache != null) {
           cache.flush();
       }
   }

开启Http Response Cache之后,Http操作相关的返回数据就会缓存到文件系统上,不仅仅是主程序自己编写的网络请求相关的数据会被缓存,另外引入的library库中的网络相关的请求数据也会被缓存到这个Cache中

清除 HttpResponseCache 的数据:

  • 缓存溢出的时候删除最旧最老的文件
  • 通过Http返回Header中的 Cache-Control 字段来进行控制的

通常来说,HttpResponseCache会缓存所有的返回信息,包括实际的数据与Header的部分.一般情况下,这个Cache会自动根据协议返回Cache-Control的内容与当前缓存的数据量来决定哪些数据应该继续保留,哪些数据应该删除。

但是在一些极端的情况下:

  • 服务器返回的数据没有设置Cache废弃的时间
  • 本地的Cache文件系统与返回的缓存数据有冲突
  • 某些特殊的网络环境导致HttpResponseCache工作异常

在这些情况下就需要我们自己来实现Http的缓存Cache。

实现自定义的http缓存,需要解决两个问题:

  1. 第一个是实现一个DiskCacheManager,
  2. 另外一个是制定Cache的缓存策略。

关于DiskCacheManager,我们可以扩展Android系统提供的DiskLruCache来实现。而Cache的缓存策略,相对来说复杂一些,我们可能需要把部分JSON数据设计成不能缓存的,另外一些JSON数据设计成可以缓存几天的,把缩略图设计成缓存一两天的等等,为不同的数据类型根据他们的使用特点制定不同的缓存策略。

0x07 参考资料

感谢以下文章作者
Android性能优化典范 - 第4季

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容