APP 的大小是分為 APP 下載大小和安裝大小兩個(gè)概念的撩轰。
- 下載大小是指 App 壓縮包(也就是 .ipa 文件)所占的空間膀哲,用戶在下載 App 時(shí)演怎,下載的是壓縮包大诸,這樣做可以節(jié)省流量捅厂;
- 當(dāng)壓縮包下載完成后贯卦,就會(huì)自動(dòng)解壓资柔,解壓過程也就是通常所說的安裝過程;安裝大小就是指壓縮包解壓后所占用的空間撵割。
用戶在App Store看到的大小是安裝大小贿堰。如果想看安裝包在各機(jī)型上的下載、安裝大小可以在 App Store Connect 后臺(tái)查看啡彬。
App Store OTA 下載大小限制:
雖然蘋果歷年都會(huì)調(diào)整 App 下載大小羹与,由之前的 100M 到后來的 150M 再到現(xiàn)在的 200M。如今庶灿,App 下載大小超出 200 MB 時(shí) 纵搁,會(huì)出現(xiàn)兩種情況:
- iOS 13 以下的用戶,無法通過蜂窩數(shù)據(jù)下載 App往踢;
- iOS 13 及以上的用戶腾誉,需要手動(dòng)設(shè)置才可以使用蜂窩網(wǎng)絡(luò)下載 App。
圖片減包
相比起代碼(5kb/千行)的平均占用來說,對(duì)圖片進(jìn)行減包是API包瘦身的最直接利职、最高效的手段
對(duì)圖片資源的處理方式包括四種
- 通過請(qǐng)求下載大圖
- 使用工具壓縮圖片
- 刪除重復(fù)圖片
- 查找復(fù)用相似圖片
方式1需要推動(dòng)落地趣效,所以本文不討論這種處理方式。
圖片壓縮
為什么png能夠無損壓縮猪贪?
UI 同事提供的PNG圖片跷敬,一般都是photoshop導(dǎo)出的,圖片存在大量的額外信息热押。
png圖片有兩種類型的數(shù)據(jù)塊西傀,
- 一種是必不可缺的數(shù)據(jù)塊稱為關(guān)鍵數(shù)據(jù)塊。
- 另一種叫做輔助數(shù)據(jù)塊桶癣,輔助數(shù)據(jù)塊在png文件中占據(jù)了極大的篇幅池凄,正是這些數(shù)據(jù)塊構(gòu)成了png的無損壓縮條件
工具推薦:ImageOptim 、圖壓 鬼廓、tinypng
tinypng進(jìn)行無損壓縮肿仑,壓縮率一般在60%-70%之間,非常高效碎税,缺點(diǎn)是只能線上壓縮
圖片資源壓縮也有很多公司使用webp
格式圖片尤慰,這種格式對(duì)比png
、jpg
要小很多雷蹂,但客戶端性能對(duì)解碼webp
圖片會(huì)有一定的影響伟端。在一些老的機(jī)型上,表現(xiàn)不是很好匪煌。所以需要做一些取舍责蝠。這里有webp
和png
格式轉(zhuǎn)換的工具 isparta
其實(shí)我覺得這兩種方案可以共存,團(tuán)隊(duì)內(nèi)部設(shè)定一個(gè)資源文件的最大值萎庭,比如超過 100KB
就選擇使用 webp
格式的圖片霜医,小于 100KB
就使用壓縮工具。這樣就可以極大的減少資源文件的大小驳规,同時(shí)減少包的體積肴敛。
刪除重復(fù)圖片
通常來說,出現(xiàn)重復(fù)圖片的原因包括 模塊間需求開發(fā)沒有打通 或是 缺少統(tǒng)一的圖片命名規(guī)范吗购。通過圖片MD5摘要是識(shí)別重復(fù)圖片的最快方法
也可以使用工具 LSUnusedResources 進(jìn)行處理
代碼文件優(yōu)化
代碼文件優(yōu)化其實(shí)可以看成是對(duì)可執(zhí)行文件 Mach-O 的優(yōu)化医男,其大小是由代碼量決定的。所以對(duì) Mach-O 瘦身捻勉,其實(shí)就是查找并減少無用的代碼
無用代碼檢測(cè)
檢測(cè)工具:WHC_Scan (使用說明)镀梭、fui工具
減少第三方SDK
- 檢查是否導(dǎo)入了相同的功能的庫
- 第三方庫大小占比很高時(shí),考慮是否要替換掉它
編譯優(yōu)化
修改 Build Setting 的相關(guān)配置踱启,可以讓我們?cè)诟斓木幾g速度报账、更小的二進(jìn)制大小撒强、更快的執(zhí)行速度之間自由選擇。這種方式的性價(jià)比很高笙什,改動(dòng)一項(xiàng)配置飘哨,就可能會(huì)帶來收益,但是可能具有一定的風(fēng)險(xiǎn)琐凭,需要謹(jǐn)慎芽隆。
-
Build Settings -> Architectures -> Excluded Architectures
刪除無用架構(gòu)
- 模擬器 32 位處理器測(cè)試需要 i386 架構(gòu);
- 模擬器 64 位處理器測(cè)試需要 x86_64 架構(gòu)统屈;
- 真機(jī) 32 位處理器需要 armv7, 或者 armv7s 架構(gòu)胚吁;
- 真機(jī) 64 位處理器需要 arm64 架構(gòu)。
刪除無用架構(gòu)
結(jié)論:
該編譯項(xiàng)在Release
下的配置應(yīng)如下
Any iOS SDK 設(shè)置為armv7 / &armv7s
愁憔;Any iOS Simulator SDK 設(shè)置為arm64
意思是Release模式下真機(jī)排除armv7 和 armv7s指令集腕扶,模擬器排除arm64(模擬器不支持arm架構(gòu))
-
Build Setting - Link-Time Optimization
鏈接時(shí)優(yōu)化 LTO(Link-Time Optimization)
對(duì)整個(gè)程序代碼進(jìn)行的一種優(yōu)化,是 LLVM 里在鏈接時(shí)進(jìn)行跨模塊間的優(yōu)化吨掌。
LTO 優(yōu)化的優(yōu)點(diǎn):
一半抱、將一些函數(shù)內(nèi)聯(lián)化:不用進(jìn)行調(diào)用函數(shù)前的壓棧、調(diào)用函數(shù)后的出棧操作膜宋,提高運(yùn)行效率與椓蓿空間利用率;
二秋茫、去除一些無用代碼:如果一段代碼分布在多個(gè)文件中史简,但是從來沒有被使用,普通的-O3
優(yōu)化方法不能發(fā)現(xiàn)跨中間代碼文件的多余代碼肛著,因此是一個(gè)局部優(yōu)化圆兵。但是Link-Time Optimization
技術(shù)可以在link
時(shí)發(fā)現(xiàn)跨中間代碼文件的多余代碼;
三枢贿、對(duì)程序有全局優(yōu)化作用:這是一個(gè)相對(duì)廣泛的概念殉农。舉個(gè)例子來說,如果一個(gè)if
方法的某個(gè)分支永不可能執(zhí)行萨咕,那么在最后生成的二進(jìn)制文件中就不應(yīng)該有這個(gè)分支的代碼统抬。
LTO 優(yōu)化的缺點(diǎn):
一、LTO 會(huì)降低編譯鏈接的速度危队,所以建議在打正式包時(shí)開啟;
二钙畔、開啟了 LTO 之后茫陆,Link Map 的可讀性明顯降低,多出了很多數(shù)字開頭的類(LTO 的全局優(yōu)化導(dǎo)致的)擎析,所以如果需要閱讀 Link Map簿盅,可以先關(guān)閉 LTO挥下;
LTO優(yōu)化
有三種選項(xiàng)可供選擇:
No
: 默認(rèn)項(xiàng),不開啟鏈接期優(yōu)化
Monolithic
: 生成單個(gè)LTO
文件桨醋,每次鏈接重新生成棚瘟,無緩存高內(nèi)存消耗,參數(shù) LLVM_LTO=YES
Incremental
: 生成多個(gè)LTO
文件喜最,增量生成偎蘸,低內(nèi)存消耗,參數(shù) LLVM_LTO=YES_THIN
結(jié)論:
該編譯項(xiàng) Release
模式下應(yīng)將 Link-Time Optimization
設(shè)為 Incremental
-
Code Generation -> Optimization Level
語言編譯優(yōu)化
-
OC
優(yōu)化:Build Settings -> Apple Clang - Code Generation -> Optimization Level
-
Swift
優(yōu)化:Build Settings -> Swift Compiler - Code Generation -> Optimization Level
OC
內(nèi)聯(lián)優(yōu)化參數(shù)如下:
- None[-O0]:Debug 模式下默認(rèn)開啟瞬内,編譯器不會(huì)優(yōu)化代碼迷雪,意味著更快的編譯速度和更多的調(diào)試信息
- Fast[-O, O1]:編譯器會(huì)優(yōu)化代碼性能并且最小限度影響編譯時(shí)間,此選項(xiàng)在編譯時(shí)會(huì)占用更多的內(nèi)存
- Faster[-O2]:編譯器會(huì)開啟不依賴空間 / 時(shí)間折中所有優(yōu)化選項(xiàng)虫蝶。在此章咧,編譯器不會(huì)展開循環(huán)或函數(shù)內(nèi)聯(lián)。此選項(xiàng)會(huì)增加編譯時(shí)間并且提高代碼執(zhí)行效率
- Fastest[-O3]:編譯器會(huì)開啟所有的優(yōu)化選項(xiàng)來提升代碼執(zhí)行效率能真。此模式編譯器會(huì)執(zhí)行函數(shù)內(nèi)聯(lián)使得生成的可執(zhí)行文件會(huì)變得更大赁严。不推薦使用此模式
- Fastest Smallest[-Os]:編譯器會(huì)開啟除了會(huì)明顯增加包大小以外的所有優(yōu)化選項(xiàng)。默認(rèn)在
Release
模式下開啟- Fastest, Aggressive Optimization[-Ofast]:啟動(dòng) -O3 中的所有優(yōu)化粉铐,可能會(huì)開啟一些違反語言標(biāo)準(zhǔn)的一些優(yōu)化選項(xiàng)误澳。不推薦使用此模式
結(jié)論
使用默認(rèn)配置即可,無需修改
Swift
編譯內(nèi)聯(lián)優(yōu)化參數(shù)如下:
- No optimization[-Onone]:Debug 模式下默認(rèn)開啟秦躯;不進(jìn)行優(yōu)化忆谓,能保證較快的編譯速度
- Optimize for Speed[-O]:Release 模式下默認(rèn)開啟;編譯器將會(huì)對(duì)代碼的執(zhí)行效率進(jìn)行優(yōu)化踱承,一定程度上會(huì)增加包大小
- Optimize for Size[-Osize]:編譯器會(huì)盡可能減少包的大小并且最小限度影響代碼的執(zhí)行效率倡缠。
核心原理
:是對(duì)重復(fù)的連續(xù)機(jī)器指令外聯(lián)成函數(shù)進(jìn)行復(fù)用,和函數(shù)內(nèi)聯(lián)的原理正好相反茎活。因此昙沦,將其開啟,能減小二進(jìn)制的大小载荔,但同時(shí)理論上會(huì)帶來執(zhí)行效率的額外消耗盾饮,對(duì)性能(CPU)敏感的代碼使用需要評(píng)估
配合其使用的還有Compilation Mode
設(shè)置,其含有兩個(gè)選項(xiàng)
1懒熙、Single File:
單個(gè)文件優(yōu)化丘损,可以減少增量編譯的時(shí)間,并且可以充分利用多核 CPU工扎,并行優(yōu)化多個(gè)文件徘钥,提高編譯速度。但是對(duì)于交叉引用無能為力
2肢娘、Whole Module:
模塊優(yōu)化呈础,最大限度優(yōu)化整個(gè)模塊舆驶,能處理交叉引用。缺點(diǎn)不能利用多核 CPU 的優(yōu)勢(shì)而钞,每次編譯都會(huì)重新編譯整個(gè) Module
Relese 模式下 -Osize 和 Whole Module 同時(shí)開啟效果會(huì)發(fā)揮的最好
結(jié)論:
Release
模式下配置為Optimize for Size[-Osize]
沙廉,Compilation Mode
選項(xiàng)改為Whole Module
-
Swift Compiler - Code Generation -> Compilation Mode
編譯模式優(yōu)化
編譯模式優(yōu)化
結(jié)論:Release
模式下配置為Whole Module
-
Linking -> Dead Code Stripping
清除無用代碼
清除無用代碼
構(gòu)建完成后,如果是 C臼节、C++ 等靜態(tài)的語言的代碼撬陵、一些常量定義,如果發(fā)現(xiàn)沒有被使用到將會(huì)被標(biāo)記為 Dead code
官疲。開啟 DEAD_CODE_STRIP = YES
這些 Dead code
將不會(huì)被打包到安裝包中
結(jié)論:默認(rèn)配置即為 YES袱结,所以使用默認(rèn)配置即可,無需修改途凫。
-
Deployment -> Strip Style
去除符號(hào)
Strip Style
表示的是我們需要去除的符號(hào)類型的選項(xiàng)垢夹,其分為三個(gè)選擇項(xiàng):
- All Symbols: 去除所有符號(hào),一般是在主工程中開啟维费;
- Non-Global Symbols: 去除一些非全局的 Symbol(保留全局符號(hào)果元,Debug Symbols 同樣會(huì)被去除),鏈接時(shí)會(huì)被重定向的那些符號(hào)不會(huì)被去除犀盟,此選項(xiàng)是靜態(tài)庫 / 動(dòng)態(tài)庫的建議選項(xiàng)而晒;
- Debug Symbols: 去除調(diào)試符號(hào),去除之后將無法斷點(diǎn)調(diào)試阅畴。
結(jié)論:主工程選擇All Symbols
倡怎,靜、動(dòng)態(tài)庫選擇Non-Global Symbols
其他
- LinkMap 可以得出每個(gè)類或者庫所占用的空間大小(代碼段+數(shù)據(jù)段)贱枣,方便開發(fā)者快速定位需要優(yōu)化的類或靜態(tài)庫 (用這個(gè)我找到了一個(gè)非常大的背景圖监署,2x的2M,3x的將近4M)刪除后效果非常明顯
參考:
圖片減包
iOS開發(fā)之ipa瘦身初探
iOS 優(yōu)化 - 瘦身
搜狐技術(shù):iOS包體積優(yōu)化實(shí)踐
推薦一個(gè)好用的工具:
WBBlades重要節(jié)點(diǎn)更新-專為提效而設(shè)計(jì)
基于Mach-O文件解析的工具集纽哥,包括無用代碼檢測(cè)(支持OC和Swift)钠乏、包大小分析(支持單個(gè)靜態(tài)庫/動(dòng)態(tài)庫的包大小分析)、點(diǎn)對(duì)點(diǎn)崩潰解析(基于系統(tǒng)日志春塌,支持有符號(hào)狀態(tài)和無符號(hào)狀態(tài))晓避。主要利用了__Text匯編代碼分析、架構(gòu)提取只壳、符號(hào)表剝離俏拱、DYSM文件提取、崩潰文件(ips)解析等技術(shù)手段實(shí)現(xiàn)吕世。
圖片相似度對(duì)比原理:像素差異比對(duì)彰触;神經(jīng)網(wǎng)絡(luò)算法;感知哈希算法
https://www.beyondcompare.cc/jiqiao/bc-iaitpdnb.html
https://blog.csdn.net/SummerCloudXT/article/details/82629348
WWDC22 App 包大小優(yōu)化
https://xiaozhuanlan.com/topic/4675012938