隨着項目工程的不斷增大,加之組件化、插件化方案盛行,致使module拆分過多,多module狀況下很容易出現依賴關係混亂、過分依賴等問題,導致構建速度成爲影響開發效率的瓶頸,想象一下修改一行代碼須要抽一根菸的功夫(可能還不夠),那一天得多費煙啊!!?java
本文針對gradle官方給出的構建優化方案結合平常開發經驗,總結了一些簡單實用的方法來提高構建速度。android
原文連接Improving the Performance of Gradle Builds。git
另外因爲目前build apk的瓶頸基本都在transformClassesWithDexBuilderForDebug這個任務(穩定佔用build時長的一半),它將全部class文件的jar包轉換爲dex,class文件越多轉換的越慢,目前有一些開源項目作了一些dex的預建立和差分合並dex的方案,簡直黑科技fastdex瞭解一下,再好比instant run這些動態化的技術咱們暫不討論。github
整個build過程分爲三個階段瀏覽器
後面的優化項都集中在configuration和execution階段。緩存
發現了構建慢的問題之後應該先找到一些工具來定量分析。bash
gradle在4.3版本發佈了build scans工具,構建時經過--scan參數完成build掃描,好比./gradlew assembleDebug --scan
。當構建完成,控制檯會打印連接,點擊連接在瀏覽器中預覽scan結果。網絡
scan結果中含有build過程的全部細節信息,好比構建日誌、構建時長、構建時間軸、task耗時分析、依賴關係、gradle插件等等,最後還會給出一些改進建議。這些信息對優化構建很是有幫助。併發
另外gradle構建時可使用profile參數生成簡易的report profile。app
./gradlew assembleDebug --profile
複製代碼
打開profile網頁長這個樣子,能夠作基本的耗時分析。
目前最新的gradle版本爲5.4.1,gradle插件版本最新爲3.4.0,使用新版gradle能夠有效利用編譯方面的優化,簡單說有新版本更新就是了。
task默認是串行執行,開啓並行執行提升構建速度org.gradle.parallel=true
(在項目根目錄gradle.properties文件中聲明),在build scan界面Timeline模塊能夠直觀的看到多任務在併發執行。
gradle默認爲構建預留1G的堆空間,但對於一個相對較大的app來講還遠遠不夠,可經過下面的配置動態調整。
org.gradle.jvmargs=-Xmx2048M
複製代碼
固然若是你的機器性能很好,還能夠調到4G甚至更高。
org.gradle.caching=true
複製代碼
此選項在gradle 3.0以後默認開啓
org.gradle.daemon=true
複製代碼
未使用的依賴庫會增長編譯時間和apk大小,應儘可能將引用去掉。
那如何排查那些不須要引用的依賴庫呢?這裏提供一個,gradle-lint-plugin完成,集成插件可排查項目中的未使用的依賴庫庫。
有些時候須要排查間接依賴,即一個library中依賴了另外一個項目中不須要使用庫,能夠經過gradle命令檢查依賴關係。
./gradlew -q :<moduleName>:dependencies
複製代碼
gradle會從用戶配置的repositories中順序的查找並下載依賴庫,build過程dependency resolution階段會執行此操做,它須要訪問網絡,所以合理配置repositories可減小依賴庫查找時間。
應用的插件究竟是全局的仍是局部的。 應該配置到合理的位置,allprojects {} or subprojects {},沒必要要的插件不要apply。
(Minimize dynamic and snapshot versions),例如「2.+」。它會迫使gradle訪問遠程倉庫判斷是否有新版本可用。 能夠去build scan界面dependencies tab下按dynamic vesion進行過濾排查。
R8是新一代的代碼壓縮工具,它的職能與Proguard相對應。在R8以前,gradle採用D8+Proguard的形式構建,R8則將混淆和D8工具整合(D8編譯器在gradle 3.1版本默認開啓),旨在加快構建時間和output apk大小。
R8的兼容模式可兼容proguard配置的混淆規則,性能方面也優於proguard。它能夠更快地縮減代碼,同時改善輸出大小。這篇文章Android代碼壓縮工具R8詳解 還總結了具體的優化數據。
R8前
R8從gradle3.3開始引入,gradle 3.4及之後默認開啓。若想在gradle3.3版本下開啓R8,gradle.properties裏添加以下配置:
android.enableR8 = false
複製代碼
在上述優化完成後,通過腳本的循環測試,編譯速度提高50%,並且還有優化空間。
階段 | 優化前 | 優化後 |
---|---|---|
clean build耗時 | 180s-200s | 90-100s |
之因此使用clean編譯是爲了模擬全量編譯的場景,若是不使用clean指令,一次編譯時間在半分鐘之內。