最近跟朋友聊天刚好聊到这一块,他们是在做电商业务,商品图片及其多,API接口请求频率也高。然而,他们在移动2/3G的网络环境下,APP经常会出现Loading很久的情况,这里我把我们所分析与使用到的网络优化方案与大家分享一下。
所谓的弱网络,也就是指在网络不好的条件下进行使用APP,如2G、3G网络,这类网络条件下,用户的网络速度基本维持在10K/S~60K/S。如此差的网络环境, 如果还希望给用户提供良好的用户体验,那么我们的APP就该想想如何优化了。
转载表明来源:http://blog.csdn.net/yzzst/article/details/51764909
需要处理在弱网络下的加载速度,那么我们要先确定一下我们的整个APP在哪个地方加载的速度如何,最长的加载路径在哪里,我们从而才有针对性的进行优化与修改。
Webview
如果是对是APP中内嵌的webview网页,针对网页体验优化已经由来已久了。我们可以使用Chrome的开发者模式,调整到Network模式下,将网络条件设置为3G去请求网页,那么我们就能够看出来一个网页加载的速度主要都好费在哪个地方,如下图所示:
当然,html的加速方式有很多种
APP API
当然很多情况下使我们的接口设计得不够合理,多次请求一个相同数据 or 慢查询造成的。我们也可以使用chrome://inspect插件,查看自己的device请求情况(Android 手机连接上adb)。如下图所示:
接口的优化理论上不属于APP弱网络的优化,但是这个的API性能的问题,确实在网络条件不好的情况下才暴露无遗。大家都在谈论服务器的好坏,设备的性能高低,其实,对于一个良好的Server来说,绝大部分拖延请求速度的地方都是在IO上。包括,磁盘读写的IO,SQL查询的IO等等。
常用的优化点:
1 . 慢查询监控
MySQL是支持慢查询日志监控的,我们能够在日志中准确的看出那一条记录的查询读写时间。具体操作大家可以查看:http://www.tuicool.com/articles/nmmimae
2 . 多次查询优化
尽量避免在For循环里面进行SQL查询!!!这个是我们最近被外包坑的心得。能够构造出一两句通过SQL查询的语句就尽量不要在代码里面处理,也不需要进行多次查询。
3 . 常用接口cache
这个cache的机制我不多说了,各式各样的cache框架,直接避免了与SQL打交道。个人觉得是不得已而为之,对于实时性要求过高的接口,还是不能采取。
说到网络优化,绝大部分都是对图片的优化。
CDN 是构建在数据网络上的一种分布式的内容分发网。 CDN
的作用是采用流媒体服务器集群技术,克服单机系统输出带宽及并发能力不足的缺点,可极大提升系统支持的并发流数目,减少或避免单点失效带来的不良影响。
公司里面使用的是阿里云的CDN服务
CDN说是可以使用最近的网络节点提供服务,避免网络传输中的消耗,但是真正的试验后我们会发现,CDN的优化毕竟有限,并不能起到体验质的飞跃。
WebP格式,谷歌(google)开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器带宽资源和数据空间。Facebook
但WebP是一种有损压缩。相较编码JPEG文件,编码同样质量的WebP文件需要占用更多的计算资源。
WebP的图片格式介绍我自己也早有耳闻,但是却没有真正的使用过。
说的再多不如我们自己手动实验一下,能够压缩多少。我们尝试将系统自带的企鹅的图片进行转化,得到如下两张图片对比:
图片从原来的760k直接变成了121k,大小仅仅为原图的 六分之一,(⊙o⊙)!!!!不敢相信。
分别打开两张图片作对比,虽然说webp是失真压缩,我们在对比查看的时候如果没有很仔细的看,确实看不出来两图的区别。细节上webp确实存在一点瑕疵,但是想到1/6的压缩,这一点点瑕疵已经无所谓了。
图片的格式更换了,我们在想想图片的精度、图片的尺寸是否也能够按照不同的情况下做下发呢?
如(对于原图是600X480的图片):
我们同样的实验了一下,得到的结果如下所示:
理论上,在网络条件不怎么好的情况下,我们能够适应情况的降低图片的大小,从而加快整个APP的加载速度。
Ok,可能很多朋友会跟我说,我艹,这么复杂的处理,不同尺寸、不同精度、不同格式的图片,我们得怎么存?我们是否每次产品方上传产品的时候都需要对图片处理,那么图床的压力得多大啊。有没有成套的解决方案?
答案是有的, 也就是我公司现在所采用的解决方案。七牛云存储(我不是广告,真心好用):
七牛云存储为企业提供图片云存储、音频云存储、视频云存储等非结构化静态文件的高速稳定安全云存储平台,快速拥有专属文件服务集群,七牛云存储用户免费享有CDN特权。
对于我们的研发来说,它们所提供的图片处理功能缺失不错。
如,我们可以在自己的仓库中设置需要处理的图片类型,如下图所示:
选择需要产生的不同图片格式,尺寸,精度模板。模板生成后,我们根据模板的内容就会得到一个参数,如下所示:
imageView2/1/w/640/h/300/format/webp/interlace/0/q/100
怎么使用呢?
如,我们在七牛上存储了一个我们自己的图片,得到的图片外链为:
http://7xujx4.com1.z0.glb.clouddn.com/o_1ank7b5fsm56af1js61g1e7js7.jpg
当然,这个图片是存储的是原图。
这个时候我们处于不同的网络条件下,希望更换尺寸、格式到上述描述的条件,我们只需要在连接上加上参数
http://7xujx4.com1.z0.glb.clouddn.com/o_1ank7b5fsm56af1js61g1e7js7.jpg?imageView2/1/w/640/h/300/format/webp/interlace/0/q/100
就将原图转化为宽度640,高度300,格式为webp,精度为100的图片了。(⊙o⊙)!!!!!
网络条件不好的条件下,我们做再多的优化也是如同治标不治本,很难达到与WiFi环境下一样的体验。既然,网络请求、缓存、压缩的方案都采取了,那么你可以想一下,是否是自己的交互,让用户感觉到卡顿、慢?
具体怎么让用户感到快,针对不同种类的APP操作不一样,这里我举几个例子:
不从0开始的进度条
如下图所示,不管网页的加载进度如何,不管网络条件如何,uc浏览器的加载进度始终是从50%起,并且停留在大约98%进度左右的地方。给予用户一种,网页马上就要加载完了的感觉。
先显示文字在加载图片
同样是在Webview之中,图片或者多媒体的加载速度肯定是远远慢过文字的加载速度的。由于不同的webview显示和渲染效果不同,我们可以先让webview先显示文字,在显示图片。给用户一种可以先预览整个网页概况的感觉。
即:
//本身含义阻止图片网络数据
webSettings.setBlockNetworkImage(true);
// 网页载入完成后,将阻塞的图片加载放开。
//解除数据阻止
webSettings.setBlockNetworkImage(false);
当然,如果是在非webview中,为了避免网络资源的消耗,也可以模仿类似的操作。
3 . 常用信息加入缓存机制、增量更新
对于APP来说,没有网络就不可用是一个硬伤,如果客户端的业务与整个公司的业务对时效性要求没有这么强烈。那么,我们是可以做到一些缓存的机制的。
如,对于今日头条APP来说,如下图所示,它们首页新闻列表,每次进入都是先从缓存中拿去出来的。每一次的刷新取得的数据,都是与服务端所推送的数据的差值(增量更新),而不是整个listview刷新。
/*
* @author zhoushengtao(周圣韬)
* @since 2016年7月16日 下午16:47:20
* @weixin stchou_zst
* @blog http://blog.csdn.net/yzzst
/