欲瘦其包,必先探清其底细
作者:閑魚技術-金喏
1.背景
??不知大家是否注意到,閑魚的包大小在隨著服務用戶的增多和新業務的持續迭代不斷增長。在過去的半年時間,Android端包大小漲了43%,iOS端也漲了26%,若再不加管控,按照目前的增長速度再過1年可直逼200M。
??包大小對應用的下載轉化率和留存率起到至關重要的作用,瘦包作為閑魚技術今年的重點項目,意義非同凡響。
??對于閑魚來說,瘦包能提升應用的下載轉化率。首先是蘋果公司不支持流量下載超過200M的包,包越大下載時間越長失敗率越高,且據Google play統計,包大小每增加6M,下載轉化率會下跌1%。此外也能提升用戶的留存率,因為當用戶手機內存不夠用時,肯定是優先刪除占內存比較大的app。
??對開發來說,定期清理廢棄代碼、不用的SDK和整理重復的資源,有助于提高代碼的健康度和架構的合理性。
??但隨著每一次客戶端發布,業務導致的增量使包大小默默攀升。業務需求是要做的,包大小也是要控的,為了讓每一次新需求集成時,開發們能切實感受到對整體包大小的影響,讓每一次包大小變動都有跡可循,需要對包大小進行科學分析。
??現在開發每次提交代碼后,會觸發打包平臺自動打包,包構建成功后會自動進行包對比分析,并發回開發包增量分析報告郵件。在介紹這個包增量分析工具之前,先給大家科普下安裝包的構成。
2.安裝包構成
2.1 Android包構成
??Android安裝包是以后綴名為“apk”的壓縮包。閑魚安裝包解壓后的主要構成如下:
??AndroidManifest.xml 配置文件:包含包名、組件、權限的配置信息等。
??resources.arsc android資源索引表:包含資源名稱、類型、值、ID和配置信息。
??classes.dex :是很多.class文件處理后的產物,最終可以在 Android 運行時環境執行。
??/assets :放置隨包打入的文件,如text、二進制數據等。
??/res 資源文件:存放圖片、字符串、布局文件、xml文件等,運行打包時沒有使用的文件資源不會打入包中。
??/lib :程序運行時依賴的庫。
2.2 iOS包構成
??iOS安裝包是后綴為“ipa”的壓縮包,解壓后主要包含以下幾部分:
??簽名文件:里面的CodeResources包含對bundle中的所有資源文件的簽名信息。
??資源文件:程序運行過程中需要的資源,比如圖片、音頻、視頻、nib文件、配置文件等。
??可執行文件:是通過編譯器、連接器將我們編寫的代碼、靜態庫、動態庫編譯成的文件,是程序的主體。其中靜態庫在鏈接時會被完整的復制到可執行文件中,被多次使用就有多份拷貝,動態庫則是鏈接時不復制,程序運行時由系統動態加載到內存,系統只加載一次,多個程序共用。
??bundle文件:工程中使用的其他第三方或資源的bundle。
3.包分析方案
3.1 Android包分析
??apk壓縮包按照資源文件類型分類,主要有:so資源(程序運行依賴的庫,如接入UC瀏覽器內核SDK時,引入的so達到驚人的12M)、圖片資源(png、webp、jpg等)、Java代碼(dex文件)、xml代碼這幾類,此外還可橫向統計flutter相關資源情況。
??由于可以拿到單個文件的信息,所以我們開發了工具解析apk包中的內容,從文件類型角度分析包資源占比情況,以及將資源文件按照大小排序展示,并以圖表形式直觀告訴開發資源情況。
3.2 iOS包分析
??我們現在是從靜態庫、動態庫、資源維度來分析包內容和增量。
3.2.1 靜態庫大小
??通過分析link map文件獲得靜態庫大小,網上有很多link map的解析工具。核心是解析link map文件中的Object files和Symbols中的數據。
#Object files: [ 0] linker synthesized [ 1] /Users/xy/build/workspace/Pods/MNN/MNN.framework/MNN(MNNReluInt8-24695ca527c0186b07.o) [ 2] /Users/xy/build/workspace/Pods/MNN/MNN.framework/MNN(MNNGemmInt16to32_4x4_Unit-416f183fdf349b160b82.o) [ 3] /Users/xy/build/workspace/Pods/MNN/MNN.framework/MNN(CPUPermute.o)??每一行代表對應可執行文件的編號,如CPUPermute.o文件編號是3。
#Symbols: #Address Size File Name 0x100006CA0 0x000000EC [ 3] __MNN10CPUPermuteC2EPNS_7BackendEPKNS_2OpE 0x100006D8C 0x0000004C [ 3] __MNN2Op15main_as_PermuteEv 0x100006DD8 0x00000008 [ 3] __MNN10CPUPermute8onResizeERKNSt3_$body 0x100006DE0 0x00000580 [ 3] __MNN10CPUPermute9onExecuteERKNSt3_$body 0x100007360 0x00000034 [ 3] __MNN38___CPUPermuteCreator__OpType_Permute__Ev 0x100007394 0x00000070 [ 3] __MNN10CPUPermuteD1Ev??在Symbols部分,Address是偏移地址,Size是所占內存大小,File所指的編號就是Object files中的文件編號,將Symbols中所有相同編號的Size累加起來,即可獲得該編號對應可執行文件的大小了。
??然后根據可執行文件的目錄信息,可知該文件所屬的靜態庫,從而計算出對應靜態庫代碼大小。此外靜態庫大小在計算時需要排除對應的dead Stripped Symbols 的大小來獲得真正的二進制大小,因為這些是無用的符號,鏈接的時候不會加入。
3.2.2 動態庫大小
??動態庫通常位于安裝文件根目錄下的Frameworks目錄中,通常是一個后綴為.framework的文件夾。
??由于動態庫在arm64架構下比較大,且蘋果在拆包階段會將打包好的通用的主二進制和動態庫拆分成單架構的主二進制和動態庫,所以只要是涉及二進制只計算arm64單架構的情況即可。
??動態庫大小是直接用lipo 拆成arm64單架構大小后計算framework文件夾占磁盤大小獲得。
3.2.3 模塊大小
??模塊大小為庫大小+該模塊所有資源文件占磁盤的大小,若為動態庫的模塊,則資源大小僅計算拷貝到主bundle的資源。分析結果如下圖所示:
3.需求增量卡口
??瘦包主要靠開發努力,要讓大家在平時開發中有瘦包的意識,最好有工具能讓開發在日常開發中清楚知道每個文件/模塊的大小,切實感受到需求集成后對整體包大小的影響和相關文件/模塊變動情況,從而促進開發進行相應的優化。
3.1 增量自動分析
??通過將前面介紹的包分析能力集成到打包腳本,在每次包構建成功時,也會同步產出基礎的包內容信息,再通過進一步的分析后獲得包中每個文件/模塊的大小情況。當代碼改動觸發重新打出新包后,文件/模塊通過一一對比的方式,找出哪些有新增,哪些被刪除,哪些內容發生變動,以及變動產生的大小,并產出對比報告郵件。通過這樣的方式讓開發對代碼增量有一個直觀感受。
??那如何讓包增量分析工具能在日常開發中持續穩定發揮作用呢,接下來介紹閑魚的需求增量卡口設計。
3.2 增量卡口設計
??在之前,閑魚的包大小差異通常都在拉出集成分支,打出版本release包時才發現,經常會震驚于這個版本的包又比上一個版本要大幾M,然后再緊急去尋找是什么需求集成導致的巨大增量。但這時發現包大小的問題已經非常滯后了,版本馬上就要發布,這個時候即使抓到了劇增的源頭,也很難在短時間內進行優化。
??因此需要增加需求集成卡口,測試通過后在合入主分支之前,經過包增量確認再集成,而不是在集成后打出release包時。現在的做法如下,開發只需要提交代碼,即可自動獲得包增量分析報告。
??其中包增量對比郵件內容,會包含與主分支最新構建、當前分支前一次構建,當前分支最初一次構建包的包大小和增量的對比結果。此外為了數據的準確性,需要開發在拉出開發分支后先構建一個基準包,并在提測和集成前合并一把主干,這樣報告數據才會更準確。
??最后是提測部分,開發同學發送提測郵件時需要標注本次提測包增量及圖片壓縮情況,若需求增量大于100K,根據超出范圍情況,需要備注原因和老板確認。bug修復期間不免也會有代碼改動,在測試完成后集成前,會再確認一次包增量情況再集成。
4.效果與展望
??閑魚需求增量卡6.20正式上線至今半月,7個客戶端新需求都收到了嚴格的卡口洗禮。以iOS為例,這半個月主干分支包大小不增反降0.5M,在開發過程中,開發也開始有意識通過優化老業務代碼和資源,為新需求增量挪出空間。
??需求增量卡口只是長效控制包大小的一個手段,加強開發在日常編碼中的瘦包意識,讓每一次需求都有跡可循,此外對于存量的資源、業務代碼清理等手段也在有序進行,flutter產物更精細的分析方案和有效的瘦身方法也在持續探索中,期待小胖魚早日瘦身成功吧~
原文鏈接:https://developer.aliyun.com/article/766949?
版權聲明:本文中所有內容均屬于阿里云開發者社區所有,任何媒體、網站或個人未經阿里云開發者社區協議授權不得轉載、鏈接、轉貼或以其他方式復制發布/發表。申請授權請郵件developerteam@list.alibaba-inc.com,已獲得阿里云開發者社區協議授權的媒體、網站,在轉載使用時必須注明"稿件來源:阿里云開發者社區,原文作者姓名",違者本社區將依法追究責任。 如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至:developer2020@service.aliyun.com 進行舉報,并提供相關證據,一經查實,本社區將立刻刪除涉嫌侵權內容。總結
以上是生活随笔為你收集整理的欲瘦其包,必先探清其底细的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人类如何面对AI挑战
- 下一篇: 如何让 Flutter 应用更好地使用