Android Gradle構建優化總結

隨着項目工程的不斷增大,加之組件化、插件化方案盛行,致使module拆分過多,多module狀況下很容易出現依賴關係混亂、過分依賴等問題,導致構建速度成爲影響開發效率的瓶頸,想象一下修改一行代碼須要抽一根菸的功夫(可能還不夠),那一天得多費煙啊!!?java

本文針對gradle官方給出的構建優化方案結合平常開發經驗,總結了一些簡單實用的方法來提高構建速度。android

原文連接Improving the Performance of Gradle Buildsgit

另外因爲目前build apk的瓶頸基本都在transformClassesWithDexBuilderForDebug這個任務(穩定佔用build時長的一半),它將全部class文件的jar包轉換爲dex,class文件越多轉換的越慢,目前有一些開源項目作了一些dex的預建立和差分合並dex的方案,簡直黑科技fastdex瞭解一下,再好比instant run這些動態化的技術咱們暫不討論。github

整個build過程分爲三個階段瀏覽器

  • initialization 準備階段
  • configuration 編譯腳本和插件,生成task列表
  • execution 執行task

後面的優化項都集中在configuration和execution階段。緩存

build scans定量分析

發現了構建慢的問題之後應該先找到一些工具來定量分析。bash

gradle在4.3版本發佈了build scans工具,構建時經過--scan參數完成build掃描,好比./gradlew assembleDebug --scan。當構建完成,控制檯會打印連接,點擊連接在瀏覽器中預覽scan結果。網絡

build_scan主界面.jpg

scan結果中含有build過程的全部細節信息,好比構建日誌、構建時長、構建時間軸、task耗時分析、依賴關係、gradle插件等等,最後還會給出一些改進建議。這些信息對優化構建很是有幫助。併發

另外gradle構建時可使用profile參數生成簡易的report profile。app

./gradlew assembleDebug --profile
複製代碼

打開profile網頁長這個樣子,能夠作基本的耗時分析。

build_profile.png

使用最新版本的Gradle

目前最新的gradle版本爲5.4.1,gradle插件版本最新爲3.4.0,使用新版gradle能夠有效利用編譯方面的優化,簡單說有新版本更新就是了。

開啓並行編譯

task默認是串行執行,開啓並行執行提升構建速度org.gradle.parallel=true(在項目根目錄gradle.properties文件中聲明),在build scan界面Timeline模塊能夠直觀的看到多任務在併發執行。

並行執行.png

調整java堆大小

gradle默認爲構建預留1G的堆空間,但對於一個相對較大的app來講還遠遠不夠,可經過下面的配置動態調整。

org.gradle.jvmargs=-Xmx2048M
複製代碼

固然若是你的機器性能很好,還能夠調到4G甚至更高。

開啓緩存build緩存

org.gradle.caching=true
複製代碼

開啓後臺進程

此選項在gradle 3.0以後默認開啓

org.gradle.daemon=true
複製代碼

去掉無用的library

未使用的依賴庫會增長編譯時間和apk大小,應儘可能將引用去掉。

那如何排查那些不須要引用的依賴庫呢?這裏提供一個,gradle-lint-plugin完成,集成插件可排查項目中的未使用的依賴庫庫。

有些時候須要排查間接依賴,即一個library中依賴了另外一個項目中不須要使用庫,能夠經過gradle命令檢查依賴關係。

./gradlew -q :<moduleName>:dependencies
複製代碼

減小引用倉庫的數量

gradle會從用戶配置的repositories中順序的查找並下載依賴庫,build過程dependency resolution階段會執行此操做,它須要訪問網絡,所以合理配置repositories可減小依賴庫查找時間。

合理的apply插件

應用的插件究竟是全局的仍是局部的。 應該配置到合理的位置,allprojects {} or subprojects {},沒必要要的插件不要apply。

不要使用動態的版本號

(Minimize dynamic and snapshot versions),例如「2.+」。它會迫使gradle訪問遠程倉庫判斷是否有新版本可用。 能夠去build scan界面dependencies tab下按dynamic vesion進行過濾排查。

檢查動態版本.png

開啓R8

R8是新一代的代碼壓縮工具,它的職能與Proguard相對應。在R8以前,gradle採用D8+Proguard的形式構建,R8則將混淆和D8工具整合(D8編譯器在gradle 3.1版本默認開啓),旨在加快構建時間和output apk大小。

R8的兼容模式可兼容proguard配置的混淆規則,性能方面也優於proguard。它能夠更快地縮減代碼,同時改善輸出大小。這篇文章Android代碼壓縮工具R8詳解 還總結了具體的優化數據。

R8前

d8+proguard.png
R8
compile_with_r8.png

R8從gradle3.3開始引入,gradle 3.4及之後默認開啓。若想在gradle3.3版本下開啓R8,gradle.properties裏添加以下配置:

android.enableR8 = false
複製代碼

總結

在上述優化完成後,通過腳本的循環測試,編譯速度提高50%,並且還有優化空間。

階段 優化前 優化後
clean build耗時 180s-200s 90-100s

之因此使用clean編譯是爲了模擬全量編譯的場景,若是不使用clean指令,一次編譯時間在半分鐘之內。

相關文章
相關標籤/搜索