AndroidStudioでビルドを高速化するTIPSを試してみる

今年は始めてGoogle I/O 2017に参加。
見たセッションの中で「Speeding up your Android Gradle builds」というものがあったので、実際に試してみた。
Android Develperにもセッションと同じ内容のものが記載されている。
https://developer.android.com/studio/build/optimize-your-build.html

「遅いビルドは普通じゃない」
遅いと感じているなら、紹介されているTIPSを幾つか試すだけでも効果がある。

実際に試して、対策前と対策後のビルド時間を比較を行ってみた。(試せるものだけピックアップ)
計測方法・・・以下のコマンドにて実施

```
$ ./gradlew clean
$ ./gradlew assembleDebug // => この時間を計測
```

ただ、セッションでも触れられていたように実際にはビルド毎に時間が微妙に変わってくるため、毎回この結果が出るわけではない。
マシンの使用状況によって結構誤差が出るので注意。
そのため以下の計測値も数回試した後の平均的な値を取る。

# Gradleのversion更新
まずはgradleとgradle pluginを最新に更新する。
https://developer.android.com/studio/releases/gradle-plugin.html
Gradleバージョン: 3.3 (比較バージョン2.14.1)
Gradle Pluginバージョン: 2.3.3 (比較バージョン2.4.3)

Build cacheにより以前に比べてだいぶビルドが早くなっている。
2.3.0以降ではデフォルトでcacheが有効化。設定により無効にする事が出来る。

### 結果
|実施前|実施後初回|実施後(Build Cache)|
|---|---|---|
|3m 0.101 s|2m 11.207s|1m 56.928s|

1分近く初回ビルドが早くなっていることが分かる。キャッシュがある場合はもっと早い。
以下、Build Cacheありの状態からどれだけ早くなるかを試してみる。

# 必要のないリソースをコンパイルしないようにする
デバッグしている機種がxxhdpiなら、xxhdpiのみを、xxxhdpiならxxxdpiのみのリソースを指定する。
また、多言語化対応しているならstringについても必要な言語のみを選択する。
今回は試しに以下を設定

```
android {
  defaultConfig {
    ...
    resConfigs "ja", "xxhdpi"
  }
}
```

### 結果
|実施前|実施後||
|---|---|---|
|1m 56.928s|1m 33.099s||

良い。特にリソースが多いプロジェクトの場合はかなり効果がありそう。

### 注意点・問題点
間違ってgitとかにpushしてしまいそう。
多言語対応や解像度別にデバッグする時に外し忘れないようにしないといけない。

# Crashlyticsをデバッグのときはコンパイルしない
Crashlyticsをデバッグ時に無効にする(Release時しか使わないなら)

```
android {
  buildTypes {
    debug {
      ext.enableCrashlytics = false
    }
  }
}
```

ちなみに、デバッグでは使うけどベータは使わないのであれば以下のようにしても効果があるらしい。
これは、クラッシュやベータ配信でビルドを識別するためのIDが自動で振られるらしいのだが、それをオフにすることで高速化。

```
android {
  buildTypes {
    debug {
      ext.alwaysUpdateBuildId = false
    }
  }
}
```

### 結果
|実施前|実施後||
|---|---|---|
|1m 56.928s|2m 17.504s||

あれ、遅くなった・・・

### 注意点・問題点
デバッグでも使うし、ベータ配信も使ってる場合は対応出来ない。

# Offline Work
Android Studio -> Preferences -> Build, Execution, Deployment -> Gradle
で、Offline workにチェックを入れる。

コマンドの場合は```--offline```を付ける。

Gradleが依存関係を解決するためにネットワークを使っている部分を無効にすることが出来る。
ネットワークに遅い場合などに有効的。

### 結果
|実施前|実施後||
|---|---|---|
|1m 56.928s|1m 36.635s||

これもなかなか効果ありそう。

# Gradleのheapを増やす
AndroidStudio2.1以降では、Gradleデーモンのヒープサイズを最低1536MBにする必要がある。
設定は、gradle.propertiesの以下の部分を変更することで対応可能。

```
org.gradle.jvmargs = -Xmx2048m
```

assembleDebugの途中で以下のようなメッセージが出ていたので、今回は試しに2560MBに設定して試してみる。
> For faster builds, increase the maximum heap size for the Gradle daemon to at least 2560 MB

### 結果
|実施前|実施後||
|---|---|---|
|1m 56.928s|1m 33.004s||

これも結構な高速になりそう。

### 注意点
開発マシンのスペックによっては限界がありそう。

# PNG Crunchingを無効にする
デフォルトだとpngリソースがビルド時に最適化されるため、一時的にオフにする。

```
android {
  aaptOptions {
    cruncherEnabled false
  }
}
```

### 結果
|実施前|実施後||
|---|---|---|
|1m 56.928s|1m 24.99s||

すごい高速化。これもリソースが多い場合に有効な手段かもしれない。

### 注意点・問題点
この設定は、[ドキュメント](https://developer.android.com/studio/build/optimize-your-build.html#disable_crunching)にも記載されている通り、Product FlavorやBuild Typeで制御出来ないため、リリース時には手動でtrueにするか、設定を削除する必要がある。gitにpushしてしまいそうで怖い。

# 全部入れてやってみる
もしかしてこれらを全部有効にしてビルドするとすごい早くなるのでは・・・
と思いながらやってみたけど劇的に変化があるわけではなかった。

### 結果

|実施前|実施後||
|---|---|---|
|1m 56.928s|1m 26.465s||

でもだいぶ早くなった。この30秒は開発を進めていく上では結構な効率化になる。

# その他: Instant Run
上記はInstant Runを無効にしていた結果。
試しにInstant Runを有効にして計測をしてみる。
初回起動は時間がかかるが、次回からのコード変更ビルドはかなり早くなる。

### 結果

|実施前|実施後||
|---|---|---|
|1m 56.928s|30s||

### 注意点
AndroidStudioのRun BuildとApply Changesのボタンが別々になったためCtrl+rではなくCmd+F10を押す必要がある。
癖で手が勝手にCtlr+rしてしまうのが残念。

# プロファイル出力
以下のコマンドでビルドすると、project-root/build/reports/profile/ ディレクトリにhtmlファイルとしてビルドにかかった時間がtask毎に見やすく出力することが出来る。

```
$ gradlew --profile --recompile-scripts --offline --rerun-tasks assemble{Flavor}Debug
```