iOS 啟動(dòng)優(yōu)化和安裝包瘦身

1 啟動(dòng)優(yōu)化

在iPhone的啟動(dòng)方式中铆惑,分為冷啟動(dòng)和熱啟動(dòng)兩種方式:

  • 1、冷啟動(dòng)(Cold Launch):從零開始啟動(dòng)APP ,需要系統(tǒng)新創(chuàng)建一個(gè)進(jìn)程進(jìn)行啟動(dòng)驱负,這是一次完整的啟動(dòng)邑雅;
  • 2片橡、熱啟動(dòng)(Hot Launch):APP已經(jīng)在內(nèi)存中,在后臺(tái)存活著淮野,再次點(diǎn)擊直接打開

我們一般說的啟動(dòng)優(yōu)化是指: 冷啟動(dòng)時(shí)的優(yōu)化捧书;

要達(dá)到優(yōu)化啟動(dòng)的目的,就需要知道在APP啟動(dòng)的時(shí)候骤星,有哪些流程经瓷,做了哪些事情;

APP的啟動(dòng)過程是從:點(diǎn)擊應(yīng)用icon圖標(biāo)洞难,到啟動(dòng)圖展示舆吮,再到首頁展示完成的過程:

打印查看啟動(dòng)時(shí)間:

通過添加環(huán)境變量可以打印出APP的啟動(dòng)時(shí)間分析(Edit scheme -> Run -> Arguments)

1、將DYLD_PRINT_STATISTICS設(shè)置為1

image.png

打印如下:


image.png

2、 如果需要更詳細(xì)的信息色冀,那就將DYLD_PRINT_STATISTICS_DETAILS設(shè)置為1

image.png

打印如下:

image.png

1.1 Main()函數(shù)執(zhí)行前

dyld(dynamic link editor):動(dòng)態(tài)鏈接器潭袱,用來裝載Mach-O文件(可執(zhí)行文件、動(dòng)態(tài)庫等)

  • dyld 加載可執(zhí)行文件mach-o文件到內(nèi)存中

    • 裝載APP的可執(zhí)行文件锋恬,同時(shí)會(huì)遞歸加載所有依賴的動(dòng)態(tài)庫
    • 當(dāng)dyld把可執(zhí)行文件屯换、動(dòng)態(tài)庫都裝載完畢后,會(huì)通知Runtime進(jìn)行下一步的處理
  • runtime加載類和分類:

    • 調(diào)用map_images進(jìn)行可執(zhí)行文件內(nèi)容的解析和處理
    • 在load_images中調(diào)用call_load_methods伶氢,調(diào)用所有Class和Category的+load方法
    • 進(jìn)行各種objc結(jié)構(gòu)的初始化(注冊O(shè)bjc類 趟径、初始化類對(duì)象等等)
    • 調(diào)用C++靜態(tài)初始化器和attribute((constructor))修飾的函數(shù)

所有初始化工作完成以后,dyld會(huì)調(diào)用main函數(shù)癣防,接下里就是UIApplicationMain函數(shù)的流程

1.1.2 啟動(dòng)優(yōu)化:

  • 1蜗巧、dyld

    • 減少動(dòng)態(tài)庫、合并一些動(dòng)態(tài)庫(定期清理不必要的動(dòng)態(tài)庫)
    • 減少Objc類蕾盯、分類的數(shù)量幕屹、減少Selector數(shù)量(定期清理不必要的類、分類)
    • 減少C++虛函數(shù)數(shù)量
    • Swift盡量使用struct
  • 2级遭、runtime

    • 用+initialize方法和dispatch_once取代所有的
    • attribute((constructor))望拖、C++靜態(tài)構(gòu)造器、ObjC的+load
  • 3挫鸽、main

    • 在不影響用戶體驗(yàn)的前提下说敏,盡可能將一些操作延遲冀瓦,不要全部都放在finishLaunching方法中
    • 按需加載

2. 安裝包ipa瘦身

官方 App Thinning

App Thinning 是由蘋果公司推出的一項(xiàng)可以改善 App 下載進(jìn)程的新技術(shù)鲁僚,主要是為了解決用戶
下載 App 耗費(fèi)過高流量的問題,同時(shí)還可以節(jié)省用戶 iOS 設(shè)備的存儲(chǔ)空間构舟。

現(xiàn)在的 iOS 設(shè)備屏幕尺寸枫匾、分辨率越來越多樣化架诞,這樣也就需要更多資源來匹配不同的尺寸和分 辨率。 同時(shí)干茉,App 也會(huì)有 32 位谴忧、64 位不同芯片架構(gòu)的優(yōu)化版本。如果這些都在一個(gè)包里角虫,那 么用戶下載包的大小勢必就會(huì)變大沾谓。

App Thinning 會(huì)專門針對(duì)不同的設(shè)備來選擇只適用于當(dāng)前設(shè)備的內(nèi)容以供下載。比如:iPhone 6 只會(huì)下載 2x 分辨率的圖片資源上遥,iPhone 6plus 則只會(huì)下載 3x 分辨率的圖片資源搏屑。

2.1、使用Asset

  • 使用Asset粉楚,將圖片區(qū)分,對(duì)應(yīng)的2X圖片和3X圖片,在上傳appStore以后會(huì)做不同的變體模软,減少下載包的大小
image.png

例如我現(xiàn)在的項(xiàng)目伟骨,由于是老項(xiàng)目,所有的圖片都是直接放在工程中的燃异,所以打包的時(shí)候沒有區(qū)分設(shè)備携狭,都會(huì)直接打包的app包中;

如果使用了現(xiàn)在的Asset回俐,將2x圖和3x圖區(qū)分開來逛腿,在appstore下載App的時(shí)候,會(huì)根據(jù)設(shè)備仅颇,只下載對(duì)應(yīng)的圖片单默,如果使用的是2x設(shè)備則只下載2x的圖片,3x的設(shè)備只下載3x的圖片忘瓦;

這樣就會(huì)減小從appstore下載時(shí)App包的大小搁廓。

2.2、刪除無用的圖片資源

項(xiàng)目中如果迭代過很多版本耕皮,圖片資源就會(huì)很多境蜕,需求在更新的同時(shí),所以可能會(huì)有很多無用的圖片凌停;

所以要使用一定的方法找到項(xiàng)目中不用的圖片粱年,并剔除掉;

  1. 通過 find 命令獲取 App 安裝包中的所有資源文件罚拟,比如 find /Users/daiming/Project/ - name台诗。
  2. 設(shè)置用到的資源的類型,比如 jpg舟舒、gif拉庶、png、webp秃励。
  3. 使用正則匹配在源碼中找出使用到的資源名氏仗,比如 pattern = @"@"(.+?)""。
  4. 使用 find 命令找到的所有資源文件夺鲜,再去掉代碼中使用到的資源文件皆尔,剩下的就是無用資源
    了。
  5. 對(duì)于按照規(guī)則設(shè)置的資源名币励,我們需要在匹配使用資源的正則表達(dá)式里添加相應(yīng)的規(guī)則慷蠕,比如
    @“image_%d”。
  6. 確認(rèn)無用資源后食呻,就可以對(duì)這些無用資源執(zhí)行刪除操作了流炕。這個(gè)刪除操作澎现,你可以使用
    NSFileManger 系統(tǒng)類提供的功能來完成。
  • 使用第三方軟件:LSUnusedResources 鏈接
image.png

下載完成以后直接運(yùn)行每辟,然后選擇工程所在的目錄剑辫,直接search,如果項(xiàng)目比較大的話渠欺,search的時(shí)間也會(huì)比較久妹蔽;

運(yùn)行以后,直接會(huì)顯示無用的圖片挠将,位置和大懈炱瘛:

image.png

這里選出來的圖片需要斟酌一下再去工程里面刪除,畢竟也是用正則表達(dá)式篩選出來的舔稀,有可能會(huì)有誤差乳丰,如果檢查過確實(shí)沒用,就可以直接刪除镶蹋。

2.3成艘、圖片資源壓縮

刪除了無用的圖片資源,有用的圖片資源其實(shí)也是可以優(yōu)化的贺归,那做法就是將圖片進(jìn)行壓縮和解壓處理:

對(duì)于 App 來說淆两,圖片資源總會(huì)在安裝包里占個(gè)大頭兒。對(duì)它們最好的處理拂酣,就是在不損失圖片 質(zhì)量的前提下盡可能地作壓縮秋冰。目前比較好的壓縮方案是,將圖片轉(zhuǎn)成 WebP婶熬。WebP 是 Google 公司的一個(gè)開源項(xiàng)目剑勾。

  • 將圖片轉(zhuǎn)化成WebP,由于將圖片轉(zhuǎn)化成WebP和解壓的過程消耗較大赵颅,所以可以將圖片大于100k的進(jìn)行轉(zhuǎn)化虽另,其他的小圖片不做處理

2.4、刪除無用代碼

App 的安裝包主要是由資源和可執(zhí)行文件組成的饺谬,所以我們在掌握了對(duì)圖片資源的處理方式后捂刺, 需要再一起來看看對(duì)可執(zhí)行文件的瘦身方法。

可執(zhí)行文件就是 Mach-O 文件募寨,其大小是由代碼量決定的族展。通常情況下,對(duì)可執(zhí)行文件進(jìn)行瘦 身拔鹰,就是找到并刪除無用代碼的過程仪缸。而查找無用代碼時(shí),我們可以按照找無用圖片的思路列肢, 即:

  1. 找出方法和類的全集;
  2. 找到使用過的方法和類;
  3. 接下來恰画,取二者的差集得到無用代碼;
  4. 最后宾茂,由人工確認(rèn)無用代碼可刪除后,進(jìn)行刪除即可锣尉。

2.4.1刻炒、使用Link Map 統(tǒng)計(jì)所有的方法和類

在build settings中搜索link map决采,然后設(shè)為YES自沧;

設(shè)置build的輸出路徑,指定一個(gè)文件夾树瞭,然后指定輸出文件的格式和名字拇厢,一般是txt格式,設(shè)置好路徑后晒喷,直接運(yùn)行孝偎,就會(huì)在指定的文件夾下生成一個(gè).txt文件;

image.png

打開txt文件凉敲,以.o結(jié)尾的衣盾,都是生成的目標(biāo)文件,如圖:

測試demo我創(chuàng)建了兩個(gè)類爷抓,一個(gè)YYPerson势决,一個(gè)YYStudent;

image.png

LinkMap 文件分為三部分:Object File蓝撇、Section 和 Symbols果复。如下圖所示:


image.png
  • Object File 包含了代碼工程的所有文件;
  • Section 描述了代碼段在生成的 Mach-O 里的偏移位置和大小;
  • Symbols 會(huì)列出每個(gè)方法、類渤昌、 block虽抄,以及它們的大小。

通過 LinkMap 独柑,你不光可以統(tǒng)計(jì)出所有的方法和類迈窟,還能夠清晰地看到代碼所占包大小的具體 分布,進(jìn)而有針對(duì)性地進(jìn)行代碼優(yōu)化忌栅。

如果項(xiàng)目較為復(fù)雜车酣,分析起來可能會(huì)很困難;

可借助第三方工具解析LinkMap文件:鏈接

運(yùn)行以后直接打開txt文件:


image.png

這個(gè)軟件能夠清晰的看到有哪些類狂秘,以及每個(gè)類的大泻Ь丁;

2.4.2者春、使用 MachOView 統(tǒng)計(jì)所有使用過的類

在products中找到.app包破衔,在finder中顯示,然后右擊顯示包內(nèi)容钱烟,找到可執(zhí)行文件:

image.png

然后使用 MachOView打開可執(zhí)行文件:

image.png

如圖上所示晰筛,我們可以看到 objc__selrefs 和 objc__classrefs 以及objc__superrefs 這三個(gè) section嫡丙。

其實(shí)這3個(gè)里面都是通過消息機(jī)制,objc__msgSend()函數(shù)調(diào)用過的對(duì)象方法读第,類方法曙博,類,元類等怜瞒;

但是父泳,這種查看方法并不是完美的,還會(huì)有些問題吴汪。原因在于惠窄, Objective-C 是門動(dòng)態(tài)語言,方法調(diào)用可以寫成在運(yùn)行時(shí)動(dòng)態(tài)調(diào)用漾橙,這樣就無法收集全所有調(diào)用的方法和類杆融。所以,我們通過這 種方法找出的無用方法和類就只能作為參考霜运,還需要二次確認(rèn)脾歇。

2.5 編譯器優(yōu)化

  • Strip Linked Product、Make Strings Read-Only淘捡、Symbols Hidden by Default設(shè)置為YES

  • 去掉異常支持藕各,Enable C++ Exceptions、Enable Objective-C Exceptions設(shè)置為NO案淋, Other C Flags添加-fno-exceptions

利用AppCode檢測未使用的代碼:菜單欄 -> Code -> Inspect Code

其實(shí)啟動(dòng)優(yōu)化和ipa瘦身座韵,在于平時(shí)的很多細(xì)節(jié),比如如果是不用的圖片踢京,要立即刪除誉碴,不用的類和方法,也要及時(shí)清理瓣距,我們一般不刪除的原因是怕以后還有可能用到黔帕,但是一般都有版本控制,刪除了以后再要用可以從之前的版本中去找蹈丸;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末成黄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子逻杖,更是在濱河造成了極大的恐慌奋岁,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荸百,死亡現(xiàn)場離奇詭異闻伶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)够话,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蓝翰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來光绕,“玉大人,你說我怎么就攤上這事畜份〉剩” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵爆雹,是天一觀的道長停蕉。 經(jīng)常有香客問我,道長顶别,這世上最難降的妖魔是什么谷徙? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮驯绎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谋旦。我一直安慰自己剩失,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布册着。 她就那樣靜靜地躺著拴孤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪甲捏。 梳的紋絲不亂的頭發(fā)上演熟,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音司顿,去河邊找鬼芒粹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛大溜,可吹牛的內(nèi)容都是我干的化漆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼钦奋,長吁一口氣:“原來是場噩夢啊……” “哼座云!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起付材,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤朦拖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后厌衔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體璧帝,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年葵诈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了裸弦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祟同。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖理疙,靈堂內(nèi)的尸體忽然破棺而出晕城,到底是詐尸還是另有隱情,我是刑警寧澤窖贤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布砖顷,位于F島的核電站,受9級(jí)特大地震影響赃梧,放射性物質(zhì)發(fā)生泄漏滤蝠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一授嘀、第九天 我趴在偏房一處隱蔽的房頂上張望物咳。 院中可真熱鬧,春花似錦蹄皱、人聲如沸览闰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽压鉴。三九已至,卻和暖如春锻拘,著一層夾襖步出監(jiān)牢的瞬間油吭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國打工署拟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婉宰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓芯丧,卻偏偏與公主長得像芍阎,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缨恒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355