前言
我司某产品产品从立项至今已经有三个年头,三年中的功能迭代导致项目中积累了大量过时的功能,把研发人员带到了业务逻辑复杂,包体积不断增长的窘境,包体积增长又会带来投放效率和转化率低下等问题。本文梳理了对包体积优化所进行的一些工作,希望能为新项目提供一定的指导作用,把包体积优化工作做得更系统、更细致和更完善,接下来从业务和技术两个大方面谈一下具体的实施办法。
方法
业务方面
首先从业务方面入手,我们知道,应用的一切复杂性均来自于业务功能,这就引入了第一个办法其实也是终极利器,梳理项目的功能,和业务方确认哪些还有存在的价值,哪些已经不再使用。对于已经不再使用的功能,要彻底地从项目中删除,这里说的彻底,其实是有个小技巧的,那就是找到当时增加这个功能的那几次提交,对着提交文件,一个一个地完整地从项目中删除。这样做还有一个好处就是,不容易引起问题,因为对于一个复杂功能,如果不能做到完整彻底地删除,容易引起应用崩溃等严重问题,笔者就曾经踩过这个坑,幸好在灰度发布时发现并及时修复了。这也要求开发者对于一个功能的提交,尽量要有规范的提交注释,方便后续定位和查找。刚刚谈到的是删除无用的功能,除此之外,还可以从需求端做一些工作,那就是保持功能和设计的简洁性,笔者个人非常推崇简洁的设计,不但使用起来赏心悦目,也能减少代码和资源的引入,简直就是一举两得。
技术方面
技术方面可以做的工作比较多,下面分门别类,综合介绍一下可以实施的办法
项目配置
- 精简支持语言:
我司应用的用户几乎都是中国人,所以我们去掉了多语言的支持,只保留了中英文两种配置,甚至可以把应用中使用字符串全写在values/string.xml中,只保留英文一种。对应的配置是
resConfigs "en", "zh-rCN"
- 精简支持的cpu架构:
目前大部分手机都支持arm-v7a,所以应用中只保留了一种架构支持,其他应用可根据实际情况,灵活选择。对应的配置是
ndk {
abiFilters 'armeabi-v7a'
}
- 只使用一套设计图:
一般情况下项目中可以只保留一套设计图比如xxhdpi, 如果某些地方适配不好,单独为它添加图片
使用工具
- proguard代码混淆
发布版本应用都会开启代码混淆,不再赘述
- lint工具
保证项目的各个module的build.gradle中有以下代码
lintOptions {
abortOnError false
}
然后在项目根目录里执行
path/to/your/gradle lint
执行结束后,会生成lint报告,有xml和html两种格式,如果未使用资源过多,html中不会展示所有的未使用资源,所以建议用浏览器打开xml格式的报告,通过全局搜索UnusedResource定位未使用资源,删除这些资源时,要反复确认,因为lint不能发现通过getIdentifier动态引用的资源(第三方代码库经常这样使用,比如豌豆荚的广告sdk)。并且删除后要仔细测试
- 资源混淆工具
笔者了解到的资源混淆工具有两种:
腾讯的AndResGuard和字节跳动的AabResGuard。具体的使用方法请参考官方提供的样例,我在我司应用中尝试过AndResGuard,使用时需要注意资源混淆的配置白名单,字节跳动的广告sdk特地提供了资源混淆白名单,需要正确的配置,否则会引起应用崩溃,对于其他sdk需要和其开发方确认是否存在动态引用的资源,如果有就将其加到资源混淆白名单中。
Apk-Checker同lint一样,也能够检查未使用的资源,它直接处理apk包,但比lint更好的一点是,能够检测文件名不同而实际内容相同的图片,这是通过文件的md5比较实现的,具体使用方法请参考官方文档。
Booster 提供了性能检测、多线程优化、资源索引内联、资源去冗余、资源压缩、系统 Bug 修复等一系列功能模块,具体接入细节参考其官方文档。它为我司应用减小了1M多的体积。需要注意的是,对于asset中的图片,如果代码中没有通过文件全名引用(比如a0.png,代码中没有使用a0.png,而是"a"+i+".png"),那么图片可能会被转成webp,导致扩展名被更改,引用出错。
其他
- 将项目中的png图片使用tinypng进行压缩
- 将项目中的图片通过AndroidStudio工具转成webp格式
- 一些可以用代码实现,也可以用图片实现时,需要做一下权衡。比如可以通过drawable实现图片的方向切换
- 尽量少使用gif图
- 尽量避免使用Lottie,它会在asset中引入json文件
结语
包体积优化是个细活,但也需要做到大处着眼,小处着手。大处就是要梳理业务功能,并及时清理过时的功能,小处就是具体到对待某一个资源,是否可以优化,是否可以删除。这个工作,需要有人一直跟进,因为一时懈怠,过一段时间,处理起来就会更加复杂。开发者最好能把包体积优化时刻记在脑海里并融入到日常开发中,最后一切的优化都需要跟进测试,优化一些就测试一些,保证产品的稳定。上述方法如果还是不能满足包体积的要求,那么可能要使用动态加载框架来动态下发功能了,本文不再深入探讨。
网友评论