Xcode Build 超加速

丁沛堯
iCHEF
Published in
5 min readJan 16, 2019

前言

相信所有的 iOS Developer 一定都有類似的經驗,每天的生活被等 Xcode rebuild 佔去了大部分的時間。以 iCHEF 為例,即使用最新的第八代 6 核心的 i7 每次 rebuild 也需要等約 50 秒左右,更別提我用自己的 2014 年 MBP ,每次 rebuild 大概都要等 5 分鐘左右。假設我每天 Build 10 次 Code ,一個月工作 22 天,一年就會浪費整整 10 個小時在等 Xcode Build ,這種時間浪費實在是讓人很不能忍啊!所以我就開始著手改善這個狀況。

成果

最後在東試試西調調以後,我主要做了以下的調整:

  • 關閉 Compile Optimization
  • 關閉 dSYM
  • 把 Framework 從 CocoaPods 移到 Carthage 管理

而經過這樣的調整後,得到了以下的成果:

```
Macbook Air :340 s -> 150 s
Mac Mini 2012 ( i5 ) :350 s -> 180 s
Mac Mini 2012 ( i7 ) :220 s -> 130 s
```

基本上所有機種的 rebuild 時間都可以降低 50 %左右。

關閉 Compile Optimization

GCC_OPTIMIZATION_LEVELSWIFT_OPTIMIZATION_LEVEL 這兩個選項是針對 Compiler 包 Binary 時的優化,包含優化 App 容量大小與執行速度,而優化的程度愈大編譯的速度就會愈慢。一般我們在 debug 時是不需要太在意 App 容量或執行速度,所以我們針對 debug mode 把這兩個 optimization 關閉以加速編譯的速度。

修改方式:

Targets -> Build Settings -> Apple Clang -Code Generation -> Optimization Level -> Debug 改為 None [-OO]

Targets -> Build Settings -> Swift Compiler -Code Generation -> Optimization Level -> Debug 改為 No Optimization [-Onone]

關閉 dSYM

dSYM 檔記錄著 debug symbols ,可以幫助我們在用戶閃退時分析閃退報告使用。但在 debug Mode 下我們是不需要分析閃退報告的(畢竟 console 就會直接告訴你發生什麼事了…),所以跟上面一樣,我們在 Debug mode 下不需要浪費額外資源去產生 dSYM 檔。

修改方式:

Targets -> Build Settings -> Debug Information Format-> Debug 改為 DWARF

把 Framework 從 CocoaPods 移到 Carthage 管理

CocoaPodsCarthage 都是很棒的套件管理軟體,這邊就不贅述兩者的優劣比較,只針對我們的主題 — Build time 來比較兩者的差異。

CocoaPods 是把第三方套件的原始碼從網路上抓下來,並且放到一個獨立的 xcodeproject 中管理,這樣的做法會導致如果你需要 rebuild 整個專案時,連同所有被 Cocoapods 管理的第三方套件都會一併 rebuild ,然後如果很不巧的你也用了 Realm 這個套件的話,就會跟我們一樣,光等 Realm build 就要等超過 30 秒以上…

相較於 CocoaPods ,Carthage 的作法則是將原始碼抓下來後就先 compile 成 dynamic framework,然後才將 dynamic framework 放到專案裡。這代表即使需要 rebuild 整個專案,也不會需要再編譯那些透過 Carthage 管理的套件。

原先我們用 CocoaPods 管理差不多 30 個套件,後來嘗試將一些套件移至Carthage 管理後,雖然第一次的 Carthage build 要等很久,但用 dynamic framework 的好處就是以後 rebuild 再也不用等 Realm 在那邊轉半天了。

目前我們採取混合使用 Cocoapods 和 Carthage 的方式,讓 Carthage 管理龐大或已經穩定的套件,Cocoapods 則管理較輕量或變動頻繁的套件。

結論

這三項調整看起來很簡單,但真正困難的點在於你要找出整個 XCode Build 的過程中造成漫長等待時間的原因在哪,而且每個專案 build 很慢的原因也都不盡相同。舉例來說,假設你的專案用到的第三方套件很少,那花費大把力氣把第三方套件從 Cocoapods 移到 Carthage 就不一定對你會有幫助,更何況過多的 dynamic framework 甚至會造成 App 啟動緩慢 的問題。所以比起『怎麼做』,我覺得更重要的是理解『為什麼要這樣做』,然後在套用到自己的專案上時才可以仔細評估這個調整是否合適。

--

--