前言
我司某產(chǎn)品產(chǎn)品從立項(xiàng)至今已經(jīng)有三個(gè)年頭,三年中的功能迭代導(dǎo)致項(xiàng)目中積累了大量過時(shí)的功能,把研發(fā)人員帶到了業(yè)務(wù)邏輯復(fù)雜,包體積不斷增長(zhǎng)的窘境,包體積增長(zhǎng)又會(huì)帶來投放效率和轉(zhuǎn)化率低下等問題懂扼。本文梳理了對(duì)包體積優(yōu)化所進(jìn)行的一些工作,希望能為新項(xiàng)目提供一定的指導(dǎo)作用右蒲,把包體積優(yōu)化工作做得更系統(tǒng)阀湿、更細(xì)致和更完善,接下來從業(yè)務(wù)和技術(shù)兩個(gè)大方面談一下具體的實(shí)施辦法瑰妄。
方法
業(yè)務(wù)方面
首先從業(yè)務(wù)方面入手陷嘴,我們知道,應(yīng)用的一切復(fù)雜性均來自于業(yè)務(wù)功能间坐,這就引入了第一個(gè)辦法其實(shí)也是終極利器灾挨,梳理項(xiàng)目的功能,和業(yè)務(wù)方確認(rèn)哪些還有存在的價(jià)值竹宋,哪些已經(jīng)不再使用劳澄。對(duì)于已經(jīng)不再使用的功能,要徹底地從項(xiàng)目中刪除蜈七,這里說的徹底秒拔,其實(shí)是有個(gè)小技巧的,那就是找到當(dāng)時(shí)增加這個(gè)功能的那幾次提交飒硅,對(duì)著提交文件溯警,一個(gè)一個(gè)地完整地從項(xiàng)目中刪除。這樣做還有一個(gè)好處就是狡相,不容易引起問題,因?yàn)閷?duì)于一個(gè)復(fù)雜功能食磕,如果不能做到完整徹底地刪除尽棕,容易引起應(yīng)用崩潰等嚴(yán)重問題,筆者就曾經(jīng)踩過這個(gè)坑彬伦,幸好在灰度發(fā)布時(shí)發(fā)現(xiàn)并及時(shí)修復(fù)了滔悉。這也要求開發(fā)者對(duì)于一個(gè)功能的提交,盡量要有規(guī)范的提交注釋单绑,方便后續(xù)定位和查找回官。剛剛談到的是刪除無用的功能,除此之外搂橙,還可以從需求端做一些工作歉提,那就是保持功能和設(shè)計(jì)的簡(jiǎn)潔性,筆者個(gè)人非常推崇簡(jiǎn)潔的設(shè)計(jì),不但使用起來賞心悅目苔巨,也能減少代碼和資源的引入版扩,簡(jiǎn)直就是一舉兩得。
技術(shù)方面
技術(shù)方面可以做的工作比較多侄泽,下面分門別類礁芦,綜合介紹一下可以實(shí)施的辦法
項(xiàng)目配置
- 精簡(jiǎn)支持語言:
我司應(yīng)用的用戶幾乎都是中國(guó)人,所以我們?nèi)サ袅硕嗾Z言的支持悼尾,只保留了中英文兩種配置柿扣,甚至可以把應(yīng)用中使用字符串全寫在values/string.xml中,只保留英文一種闺魏。對(duì)應(yīng)的配置是
resConfigs "en", "zh-rCN"
- 精簡(jiǎn)支持的cpu架構(gòu):
目前大部分手機(jī)都支持arm-v7a未状,所以應(yīng)用中只保留了一種架構(gòu)支持,其他應(yīng)用可根據(jù)實(shí)際情況舷胜,靈活選擇娩践。對(duì)應(yīng)的配置是
ndk {
abiFilters 'armeabi-v7a'
}
- 只使用一套設(shè)計(jì)圖:
一般情況下項(xiàng)目中可以只保留一套設(shè)計(jì)圖比如xxhdpi, 如果某些地方適配不好,單獨(dú)為它添加圖片
使用工具
- proguard代碼混淆
發(fā)布版本應(yīng)用都會(huì)開啟代碼混淆烹骨,不再贅述
- lint工具
保證項(xiàng)目的各個(gè)module的build.gradle中有以下代碼
lintOptions {
abortOnError false
}
然后在項(xiàng)目根目錄里執(zhí)行
path/to/your/gradle lint
執(zhí)行結(jié)束后翻伺,會(huì)生成lint報(bào)告,有xml和html兩種格式沮焕,如果未使用資源過多吨岭,html中不會(huì)展示所有的未使用資源,所以建議用瀏覽器打開xml格式的報(bào)告峦树,通過全局搜索UnusedResource定位未使用資源辣辫,刪除這些資源時(shí),要反復(fù)確認(rèn)魁巩,因?yàn)閘int不能發(fā)現(xiàn)通過getIdentifier動(dòng)態(tài)引用的資源(第三方代碼庫(kù)經(jīng)常這樣使用急灭,比如豌豆莢的廣告sdk)。并且刪除后要仔細(xì)測(cè)試
- 資源混淆工具
筆者了解到的資源混淆工具有兩種:
騰訊的AndResGuard和字節(jié)跳動(dòng)的AabResGuard谷遂。具體的使用方法請(qǐng)參考官方提供的樣例葬馋,我在我司應(yīng)用中嘗試過AndResGuard,使用時(shí)需要注意資源混淆的配置白名單肾扰,字節(jié)跳動(dòng)的廣告sdk特地提供了資源混淆白名單畴嘶,需要正確的配置,否則會(huì)引起應(yīng)用崩潰集晚,對(duì)于其他sdk需要和其開發(fā)方確認(rèn)是否存在動(dòng)態(tài)引用的資源窗悯,如果有就將其加到資源混淆白名單中。
Apk-Checker同lint一樣偷拔,也能夠檢查未使用的資源蒋院,它直接處理apk包亏钩,但比lint更好的一點(diǎn)是,能夠檢測(cè)文件名不同而實(shí)際內(nèi)容相同的圖片悦污,這是通過文件的md5比較實(shí)現(xiàn)的铸屉,具體使用方法請(qǐng)參考官方文檔。
Booster 提供了性能檢測(cè)切端、多線程優(yōu)化彻坛、資源索引內(nèi)聯(lián)、資源去冗余踏枣、資源壓縮昌屉、系統(tǒng) Bug 修復(fù)等一系列功能模塊,具體接入細(xì)節(jié)參考其官方文檔茵瀑。它為我司應(yīng)用減小了1M多的體積间驮。需要注意的是,對(duì)于asset中的圖片马昨,如果代碼中沒有通過文件全名引用(比如a0.png竞帽,代碼中沒有使用a0.png,而是"a"+i+".png")鸿捧,那么圖片可能會(huì)被轉(zhuǎn)成webp屹篓,導(dǎo)致擴(kuò)展名被更改,引用出錯(cuò)匙奴。
其他
- 將項(xiàng)目中的png圖片使用tinypng進(jìn)行壓縮
- 將項(xiàng)目中的圖片通過AndroidStudio工具轉(zhuǎn)成webp格式
- 一些可以用代碼實(shí)現(xiàn)堆巧,也可以用圖片實(shí)現(xiàn)時(shí),需要做一下權(quán)衡泼菌。比如可以通過drawable實(shí)現(xiàn)圖片的方向切換
- 盡量少使用gif圖
- 盡量避免使用Lottie谍肤,它會(huì)在asset中引入json文件
結(jié)語
包體積優(yōu)化是個(gè)細(xì)活,但也需要做到大處著眼哗伯,小處著手荒揣。大處就是要梳理業(yè)務(wù)功能,并及時(shí)清理過時(shí)的功能焊刹,小處就是具體到對(duì)待某一個(gè)資源乳附,是否可以優(yōu)化,是否可以刪除伴澄。這個(gè)工作,需要有人一直跟進(jìn)阱缓,因?yàn)橐粫r(shí)懈怠非凌,過一段時(shí)間,處理起來就會(huì)更加復(fù)雜荆针。開發(fā)者最好能把包體積優(yōu)化時(shí)刻記在腦海里并融入到日常開發(fā)中敞嗡,最后一切的優(yōu)化都需要跟進(jìn)測(cè)試颁糟,優(yōu)化一些就測(cè)試一些,保證產(chǎn)品的穩(wěn)定喉悴。上述方法如果還是不能滿足包體積的要求棱貌,那么可能要使用動(dòng)態(tài)加載框架來動(dòng)態(tài)下發(fā)功能了,本文不再深入探討箕肃。