【性能优化】Android图片优化
前言
如今图片已经是app非常重要的一部分,它比文字更有表现力也更容易为用户认知。在移动开发中,图片优化也是非常重要的一部分,通常有以下三个目的:
1. 加快图片加载效率,提升用户体验。
2. 增强应用稳定性,减少oom发生概率。
3. 降低图片存贮流量成本,降低技术成本。
背景
app中加载图片通常包含两块,一块是打包到apk内部的图片文件,比方说res和asset目录下的;另一块是在程序运行时动态加载的图片,发起的来源有native h5等。而这两块优化的思路有很多相似的地方也有很多差异。
做性能优化,既要有全局性也要专研细节,才能有的放矢抓住痛点。我们先大概看下android加载图片的流程:
1. 获取图片地址
2. 下载图片到本地
3. 解码生成Bitmap
4. 绑定到视图交给GPU渲染
由此可以看到,图片加载主要有两块核心:网络和图片编解码。
网络优化
app在请求图片时,下载网络会占用很大部分时间,特别是在移动网络情况下,图片加载会非常缓慢而且容易出错。
解决网络问题一般可以由两个思路入手,一方面提升连接稳定性和效率,另一方面减少网络传输的距离。
连接效率
在传统图片库中,大家都使用了jdk自带的HttpUrlConnection来处理网络请求(apache httpclient已不推荐使用)。默认行为采用的是http 1.1协议,http 1.1协议有很大的缺陷,比如请求开销太大只能串行工作等,并且需要开启keep-alive才能复用链接。底层的tcp需要3次握手才能开始工作,这在弱网情况下是明显的瓶颈。特别是全面https化后,ssl的建连需要更多的交互。
Http 1.1协议已经是运行了十多年的协议,国际上也明显认识它的不足。对此,google推出了spdy协议,而Http2也是基于spdy协议应运而生。
Http3目前也在筹备当中,其中重要一点就是基于google的QUIC协议。
Http2协议主要有以下好处:
1. 将数据进行二进制分帧处理
2. header数据支持压缩
3. 支持完全的单路复用
4. 支持server push
5. 支持请求优先级
可以看到Http2针对1.1的弱点做了针对性优化,可以提升请求效率。Nignix已经开发出支持Http2协议的模块,端上使用okhttp作为网络库即可。
而ssl原理和优化策略可以参加TLS 1.3协议,这里就不具体展开了。
网络距离
一般地,距离越远请求的时延就越高,而且更加容易出错。而且在国内特色环境下,存在多个网络服务商,而跨网访问就更慢了。同时图片媒体这种数据量大的东西对于服务器带宽也产生了非常大的压力,于是聪明的人就想出了cdn这个方案。把静态资源分散到全世界各个地区节点上,让用户能够更快访问。目前国内也有很多成熟cdn解决方案,比如说阿里云、七牛等。
另一方面,大部门图片库也会在本地增加磁盘缓存,将已经请求过的网络缓存在本地,提升加载效率。(Picasso的磁盘缓存需要特殊配置才行。)说到缓存,大部分人第一时间想到的就是LRU,但其实LRU只是缓存淘汰的一种策略,还有很多其他的淘汰策略比如FIFO、LFU等。评估缓存应当包含以下几个方面:
1. 缓存容量及存贮分布方式
2. 缓存访问及更新方式
3. 缓存淘汰策略
4. 缓存命中率
不同业务对于缓存的要求是不一样的,需要对上午因素仔细评估,选取合适自己业务发展的缓存。
图片编解码
将网络下载之后,接下来就是需要对图片进行解码,而解码操作是cpu密集工作,对于性能也有很大影响。而产生影响的主要有两大块因素:图片格式和体积。
这里就不详细说各种图片的编码原理,大家有兴趣可以自行google。
图片格式
一般常见的图片格式有jpg和png,这两种格式各有优点。一般地jpg的体积更小,而png支持alpha通道。此外地,在android开发还可以使用向量图片,体系更小而且放大不会失真。
而各大厂并不满足于此,也在不断研发追求更好的格式。Google就推出了webp格式,webp可以保证相同图片质量可以将体积控制的更小。苹果也是有自己的Heif格式,腾讯也提出了自己的tpg格式。
不同图片格式需要不同的解码库支持,android默认只支持jpg和png格式,在4.0系统以后可以支持webp格式,4.2之后支持webp的alpha通道。
图片体积
如上面所说,图片体系也会跟编码方式有关,一般由大到小为png>jpg>webp>vd。
如今手机摄像头像素越来越高,拍摄的图片体积也越来越大,动辄就是几Mb十几Mb。如果图片来自用户主动上传的图片,不做任何处理图片加载的效率是非常慢的。对此我们就可以根绝场景进行优化,减少图片体积和解码体积。我们可以解除大部分cdn支持的图片动态裁剪特性,减少图片体积。而解码过程中也提供了一些参数优化解码如inSampleSize、区域解码等。
在app内选择图片可参考以下原则:
后记
以上只是简单介绍了图片优化的原理和常用策略,要真正做好图片优化,还需要更加深入原理和细节,从点滴入手持续优化。如果有什么问题,欢迎一起探讨。