優化建置速度

Optimize Build Speed

Photo by Alternate Skate on Unsplash

Gradlew

在動工前先用gradlew指令看看實驗前,實驗後的結果看看吧!那gradlew是什麼呢?在講gradlew前先了解下Gradle這個可能很親近卻陌生的工具。

Gradle是一個構建工具,它用來幫助我們構建app,構建包括編譯打包等過程。我們可以為Gradle指定構建規則,那我們想用gradle的指令構建app,就需要用到gradlew(即gradle wrapper的簡寫)。

那如果想詳細了解gradlew的相關指令可以參考下方這篇文章,寫得非常詳盡。
Android工具學習之gradlew最全指令攻略

  1. 清除gradlew,開啟android studio選擇專案後,點選下方Terminal並輸入下方gradlew指令,清空gradlew。
    ./gradlew clean
  2. 接著依照你專案的名稱下去更換,中間的命令也可以參考gradlew進行更換,但最主要的是Flavor將它更換成你的build專案名稱。這邊就先照Google devlopers來做吧!可以參考這篇Profile your build
    ./gradlew --profile --offline --rerun-tasks assembleFlavorDebug
  3. 結束後會產出個html的報告,放在你專案資料夾底下,進入專案資料夾後路徑如下。
    build => reports => profile => profile-2020-01-03-17-09-34.html

用預覽器開啟這個html檔就會看到如下圖的報告了。

profile-2020-01-03-17-09-34.html

到目前為止你已經會使用gradlew指令產出profile report了,接著就來開始動手優化建置速度吧!

優化建置速度

1. update gradle version

最新的Gradle version可以參考右側的連結Android Gradle plugin release notes

"+" 代表添加;"-" 代表刪除

build.gradle

2. Avoid legacy multidex

在Android Sutdio 2.3版本後已經預設幫你處理這部分的事情了,因此不必在defaultConfig設定後又在productFlavors啟動一次multidex,所以放心的拿掉productFlavors裡的minSdkVersion 21吧!

build.gradle

那啟動它會花多久?這會讓專案建置又拖了幾秒鐘?讓我們來看看Google I/O ‘17的圖表吧!

Google I/O ‘17 Avoid multidex

3. Disable multi apk

這裡就要看你的build type了,在Google I/O ‘17中他們是針對gradle.properties file中是否有devBuild下去設定,但我只想要在build是dev時才做disable,因此就Google到了另一種方式,兩種都會附上去給大家看看你需要哪一種。

Google I/O ‘17
Exclude specific build variants

因為Google I/O ‘17沒有放實測數據,那我們就來測試下來會差多少呢?
在這邊我們實測下來大概快了35秒,下面來看下報告吧~

splits abi & density open
splits abi & density close

4. include minimal resources

賦予debug專案指定的資源檔,這也有助於加快建置速度,但如果你都使用webp的圖檔的話那這段其實幫助沒有到這麼顯著,稍後會解釋webp。

build.gradle

5. Disable PNG crunching

禁用PNG,原因是因為PNG在進行建置時會再進行處理,如果改用Webp後就不用PNG了,如果一定要用PNG可以略過此方法,用上方指定資源檔即可。那這邊我同樣附給大家Google I/O及我的版本,差異如下。

Google I/O ‘17
Exclude specific build variants

那一樣看看Google I/O ‘17的圖表,了解下差異有多少。

6. Use WebP

那怎麼創建WebP呢?這裡很貼心的可以使用Android Studio直接轉換的方法就參照官方開發者文件說明拉!請參考此篇Create WebP images

替換完後會差到多少呢?這邊實測下來大約差到30秒,做到這裡拼拼湊湊起碼也一分鐘了。

Use PNG & JPG
Use Webp

7. Disable Crashlytics and Update Frabic BuildId

相信各位Android工程師一定有使用過Firebase的產品,在這裡可以在特定build type中關閉,因為Crashlytics及Fabic BuildId都會拖慢建置速度。

我這邊是想在build type是dev時且又是debug下載禁用crashlytics,所以才會演變下方的方式。

Application
build.gradle

那這樣快了幾秒呢?測下來大概快了5秒鐘

Open Crashlytics and Update Frabic BuildId
Close Crashlytics and Update Frabic BuildId

8. Don’t use dynamic versions

因為使用dynamic version會讓專案每次建置時都需要上去拉一次最新的資源,而且也有可能會因為新版與舊版不相容,間接增加穩定性降低的風險,所以應該如下實作。

Bad : implementation 'com.lokalise.android:ota-sdk:1.+'

Good : implementation 'com.lokalise.android:ota-sdk:1.3.15'

9. 民間偏方

接下來官方大補帖都試完了,就輪到民間偏方了以下是我嘗試的民間偏方,kapt我沒有完整實作,因為試下去好像沒有顯著效果不然原本想對room使用此方式。

build.gradle
gradle.properties

總結

優化就跟賽車一樣,為的就是榨出這輛車的每匹馬力,把性能逼至極限,純粹為了那幾毫秒的勝利,最後給大家兩句Gradlew指令可以了解下自己調教出來的建置速度有沒有達到自己心中的目標呢?

產出原始未優化報告

產出優化後報告

最後附上Before & After感謝讀完!

Before
After

--

--

陳建維 Ben
工程師求生指南(Sofware Engineer Survival Guide)

喜愛新鮮知識充滿好奇心的Mobile工程師,3C愛好者也是書蟲。連絡信箱:tttw216@gmail.com;目前遷移至我的Blog: https://awilab.com/