Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Build高速化の話
Search
kobito-kaba
November 20, 2017
Programming
2.4k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Build高速化の話
.droidconSFのJared Burrowsによる、"Make Your Build Great Again"を試してみたら、ビルド時間が半分になりましたので、まとめました
kobito-kaba
November 20, 2017
More Decks by kobito-kaba
See All by kobito-kaba
新規プロジェクトでやってよかったことまとめ
kobitokaba
1
930
Youtube like BottomNavigation
kobitokaba
0
280
Modularizing and Refactoring Android App with Clean Architecture
kobitokaba
0
300
Slice Your App
kobitokaba
2
1.3k
Inside Jetpack
kobitokaba
2
170
Generating and Transforming Kotlin code
kobitokaba
0
140
Conference Tourism
kobitokaba
0
300
Inside Jetpack Architecture Components
kobitokaba
0
250
Kotlinもう一歩
kobitokaba
8
17k
Other Decks in Programming
See All in Programming
App Intentsのビルドプロセスを支える技術
kntkymt
0
200
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
350
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
320
iOS開発×AI駆動開発 〜最近使って便利だったスキルの話〜
nogu66
0
140
Building an Out-of-Order CPU
latte72
1
750
業務時間外もAIに働いてもらう話
colorful12
3
10k
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
360
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
520
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
140
Hono + Inertia + React で LP を構築した話
oukayuka
2
220
自分的「カンファレンスの楽しみ方」
syumai
0
200
アクセシビリティから考える情報設計
high_g_engineer
0
350
Featured
See All Featured
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
270
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
The Language of Interfaces
destraynor
162
27k
Building AI with AI
inesmontani
PRO
1
1.2k
How to build a perfect <img>
jonoalderson
1
6k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
What's in a price? How to price your products and services
michaelherold
247
13k
Evolving SEO for Evolving Search Engines
ryanjones
0
280
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
Docker and Python
trallard
47
4.2k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
Transcript
Build高 化 お話 Yahoo! JAPAN 森 洋之
None
Make Your Build Great Again!
Jared Burrows Software Engineer @Microsoft Yammer for Android
Before After Reduction Time(min) 〜18+ 〜11 38.89%
ビルド 度 ために 最適化する対象
• ソフトウェア ◦ Gradle ◦ Android Gradle Plugin ◦ Android
Studio / IntelliJ • ハードウェア ◦ CPU ◦ メモリ
None
$4,999〜
探るべきも • 遅くなっている原因 • ボトルネックになっているタスク • 不要な依存関係・プラグイン • モジュール/build.gradle 構
スタート地点 • 一番ベースとなっているところから手を付けていく
スタート地点 • 一番ベースとなっているところから手を付けていく • PCを変える、ビルドエージェントを見直すなど
スタート地点 • 一番ベースとなっているところから手を付けていく • PCを変える、ビルドエージェントを見直すなど • Gradle 設定を最適化する
スタート地点 • 一番ベースとなっているところから手を付けていく • PCを変える、ビルドエージェントを見直すなど • Gradle 設定を最適化する • Android
Gradle Plugin 設定を最適化する
スタート地点 • 一番ベースとなっているところから手を付けていく • PCを変える、ビルドエージェントを見直すなど • Gradle 設定を最適化する • Android
Gradle Plugin 設定を最適化する • Android Studio 設定を最適化する
Gradle 設定
基本
ソフトウェアを最新にする • Gradle 4.3を使う
None
ソフトウェアを最新にする • Gradle 4.3を使う • マイナーバージョン間 互換性を維持する
ソフトウェアを最新にする • Gradle 4.3を使う • マイナーバージョン間 互換性を維持する • JVMも最新 も
を使う
gradle.properties
Gradle daemonを有効にする • Gradleを実行するたびに、新しいインスタンスを 立ち上げている • デーモンを使用することで、ビルドごとにJVMを起動す るコストを避けられる • 3.0〜
デフォルトで有効
gradle.properties org.gradle.daemon=true
daemon ヒープサイズを増やす • デフォルトで 1GB • Androidプロジェクト 、通常もっと使う • AGP
2.1以上だと、”Dex in Process”に 最低2GB 必要 • 大きなプロジェクトほど、メモリ 増設が効く
gradle.properties org.gradle.daemon=true
gradle.properties org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m
並列ビルドを有効にする • Gradleタスク 並列実行 ビルド 度を くする • モジュール分割されたプロジェクトで効果的 •
JavaCompileタスクを別プロセスで行うと良い • テストタスクも別プロセスが良い
gradle.properties org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m
gradle.properties org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m org.gradle.parallel=true
Javaコンパイルタスクを分離する tasks.withType(JavaCompile) { options.fork = true }
テストタスクを分離する tasks.withType(Test) { def maxCount = gradle.startParameter.maxWorkerCount maxParallelForks = (maxCount
< 2) ? 1 : maxCount / 2 forkEvery = 100 }
None
Configure on Demandを有効にする • 関係 あるモジュール/タスクで み Configurationを行う • モジュール分割されたプロジェクトで効果的
• こ 設定をしても、“subprojects”や”allprojects”で 設定を使うと無意味になる
gradle.properties org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m org.gradle.parallel=true
gradle.properties org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m org.gradle.parallel=true org.gradle.configureondemand=true
ビルドキャッシュを有効にする • インクリメンタルビルドによって、 無駄な再ビルドを減らすことができる • ブランチを変えたときにも効果的 • 異なるビルドフレーバーをビルドする時に効果的
gradle.properties org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m org.gradle.parallel=true org.gradle.configureondemand=true
gradle.properties org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true
build.gradle
プラグイン 適用 よく考えて • 必要なモジュールにだけプラグインを適用する • “subprojects” / “allprojects”を使う 、
本当に実際に使用しているプラグインだけにする
参照するリポジトリを減らす よくあるやつ • jcenter() • mavenCentral() • maven { url
“https://plugins.gradle.org/m2/” } • maven { url “https://maven.google.com” } • maven { url “https://jitpack.io” }
参照するリポジトリを減らす repositories { jcenter() mavenCentral() maven { url “https://plugins.gradle.org/m2/” }
google() maven { url “https://jitpack.io” } }
参照するリポジトリを減らす repositories { maven { url “https://plugins.gradle.org/m2/” } google() }
// これでいけるかも?
動的バージョン指定 避ける(+) • そもそも警告されていると思うが • 意図しないアップデートが発生する • バージョン比較 難しい •
毎回バージョンチェックして遅くなる
動的バージョン指定 避ける(+) dependencies { // ダメ implementation ‘com.android.support:appcompat-v7:+’ }
最新 バージョンを探す goo.gl/qy5uJa プロジェクト 依存ライブラリ 、 最新バージョンを探してレポートするプラグイン
動的バージョン指定 避ける(+) こうすると ./gradlew dependencyUpdates -Drevision=release
動的バージョン指定 避ける(+) ------------------------------------------------------------ : Project Dependency Updates (report to plain
text file) ------------------------------------------------------------ The following dependencies are using the latest release version: - com.android.support.test.espresso:espresso-core:3.0.1 - com.github.ben-manes:gradle-versions-plugin:0.17.0 - junit:junit:4.12 - com.android.support.test:runner:1.0.1 The following dependencies have later release versions: - com.android.support:appcompat-v7 [26.1.0 -> 27.0.1] - com.android.support.constraint:constraint-layout [1.0.2 -> 1.1.0-beta3] - com.android.tools.build:gradle [3.0.0 -> 3.1.0-alpha03] - org.jacoco:org.jacoco.agent [0.7.4.201502262128 -> 0.7.9] - org.jacoco:org.jacoco.ant [0.7.4.201502262128 -> 0.7.9]
動的バージョン指定 避ける(+) ------------------------------------------------------------ : Project Dependency Updates (report to plain
text file) ------------------------------------------------------------ The following dependencies are using the latest release version: - com.android.support.test.espresso:espresso-core:3.0.1 - com.github.ben-manes:gradle-versions-plugin:0.17.0 - junit:junit:4.12 - com.android.support.test:runner:1.0.1 The following dependencies have later release versions: - com.android.support:appcompat-v7 [26.1.0 -> 27.0.1] - com.android.support.constraint:constraint-layout [1.0.2 -> 1.1.0-beta3] - com.android.tools.build:gradle [3.0.0 -> 3.1.0-alpha03] - org.jacoco:org.jacoco.agent [0.7.4.201502262128 -> 0.7.9] - org.jacoco:org.jacoco.ant [0.7.4.201502262128 -> 0.7.9]
動的バージョン指定 避ける(+) ------------------------------------------------------------ : Project Dependency Updates (report to plain
text file) ------------------------------------------------------------ The following dependencies are using the latest release version: - com.android.support.test.espresso:espresso-core:3.0.1 - com.github.ben-manes:gradle-versions-plugin:0.17.0 - junit:junit:4.12 - com.android.support.test:runner:1.0.1 The following dependencies have later release versions: - com.android.support:appcompat-v7 [26.1.0 -> 27.0.1] - com.android.support.constraint:constraint-layout [1.0.2 -> 1.1.0-beta3] - com.android.tools.build:gradle [3.0.0 -> 3.1.0-alpha03] - org.jacoco:org.jacoco.agent [0.7.4.201502262128 -> 0.7.9] - org.jacoco:org.jacoco.ant [0.7.4.201502262128 -> 0.7.9]
不要な / 使用してないライブラリを避ける • でかいライブラリ 避ける • 同様 機能で、より軽量 ライブラリを使用する
Jacksonより 、Gson / Moshiを選ぶ Guava 使わない • 詳しく goo.gl/miu6aV
インクリメンタルビルドを有効にする • 修正したクラスと、それに依存するクラスだけ コンパイルする
インクリメンタルビルドを有効にする tasks.withType(JavaCompile) { options.fork = true }
インクリメンタルビルドを有効にする tasks.withType(JavaCompile) { options.incremental = true options.fork = true }
インクリメンタルビルドを有効にする • AutoValue / Glide / Butterknife / Dagger等、 APTを行うライブラリ
、インクリメンタルビルドを無効 化する • Android Gradle Plugin(AGP) 3.0〜 APTもサポートされている…?
None
Android Gradle Plugin
ソフトウェアを最新にする • AGP 3.0.0を使う • SDK tools / platform toolsも最新
も を使う
不要なリソース コンパイルを避ける • “resConfig”で、必要ないローカリゼーションを 除外することができる • 自分 とこ 、日本語リソースしかないけど? →外部ライブラリ
、そうでもない で ?
不要なリソース コンパイルを避ける android { defaultConfig { resConfigs “ja” } }
// 日本語だけ
不要なリソース コンパイルを避ける android { defaultConfig { resConfigs “ja”,”en” } }
// 日本語と英語
定数を使う android { compileSdkVersion 27 buildToolsVersion “27.0.0” defaultConfig { applicationId
“com.example.android.hmori.sample” versionCode new Date().format(“ddMMyyHHmm”).toInteger() versionName “1.0” minSdkVersion 19 targetSdkVersion 27 } }
定数を使う android { compileSdkVersion 27 buildToolsVersion “27.0.0” defaultConfig { applicationId
“com.example.android.hmori.sample” versionCode new Date().format(“ddMMyyHHmm”).toInteger() versionName “1.0” minSdkVersion 19 targetSdkVersion 27 } }
定数を使う def isRelease = project.hasProperty(“release”) android { compileSdkVersion 27 buildToolsVersion
“27.0.0” defaultConfig { applicationId “com.example.android.hmori.sample” versionCode isRelease ? new Date().format(“ddMMyyHHmm”).toInteger() : 1 versionName “1.0” minSdkVersion 19 targetSdkVersion 27 } }
ライブラリモジュールに分割する • Gradle 修正したモジュールだけコンパイルする • コンパイル結果 キャッシュされる • モジュール分割 +
“configurationOnDemand” + 並列ビルドが効果的
PNG crunchを無効にする • PNGをWebPに変換できないなら、 PNG crunchを使う • 無効にすることで、AGP ビルドごとにPNGを 再圧縮すること
なくなる • AGP 3.0.0〜、PNG crunch 、 ”debug”ビルド時に 、デフォルトで無効
PNG crunchを無効にする android { aaptOptions { cruncherEnabled = project.hasProperty(“ci”) }
}
lagacyなmultidexを避ける • minSdkVersion < 21 : legacyなmultidex • minSdkVersion >=
21 : ネイティブでmultidexがサポートされている • 開発時 み、minSdkVersionを21以上になるように すれ 、開発時 ビルドが くなる
lagacyなmultidexを避ける android { compileSdkVersion 27 buildToolsVersion “27.0.0” defaultConfig { applicationId
“com.example.android.hmori.sample” versionCode 1 versionName “1.0” minSdkVersion 19 targetSdkVersion 27 } }
lagacyなmultidexを避ける android { compileSdkVersion 27 buildToolsVersion “27.0.0” defaultConfig { applicationId
“com.example.android.hmori.sample” versionCode 1 versionName “1.0” minSdkVersion rootProject.hasProperty(“lollipop”) ? 21 : 19 targetSdkVersion 27 } }
CIで pre-dexライブラリを無効化する • pre-dex インクリメンタルビルドで 効果的 • CIでクリーンビルドするときに 無駄
CIで pre-dexライブラリを無効化する android { dexOptions { preDexLibraries = !project.hasProperty(“ci”) }
}
ビルドキャッシュを有効にする • AGP 幾つか 生成物をキャッシュする • AGP 2.3.0〜 デフォルトで有効
gradle.properties # Gradle specific org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true
gradle.properties # Gradle specific org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true #
Android specific android.enableBuildCache=true
新しいDEXコンパイラを有効にする • DEXコンパイラ 、.class → .dexに変換する • D8 より早く.dexファイルに変換する。 •
しかも生成物 より小さくなる • しかも実行時パフォーマンスも改善する • AGP 3.1.0〜デフォルトで有効
gradle.properties # Gradle specific org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true #
Android specific android.enableBuildCache=true
gradle.properties # Gradle specific org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true #
Android specific android.enableBuildCache=true android.enableD8=true
Android Studio 設定
画像をWebPにする • WebPにすることで、画像サイズを削減できる • ビルド時にやる必要 ない • ビルド前にやっておくことで、 ビルド時間 改善される
画像をWebPにする • “drawable”フォルダを右クリック
Instant Runを有効にする • 一定 コード追加やリソース修正で、 新しくAPKファイルを作成せずに実行できる • 特定 場合に 、アクティビティ
再起動さえ いらない
offline modeを有効にする • dependencyやプラグインを頻繁に更新しない な ら、offline modeで更新チェックを外すといい • ./gradlew --offline
offline modeを有効にする • Preferences ”Build, Execution, Deployment”
Profiling Your Build
ビルドプロセスをプロファイルする • “gradlew --profile” • “gradlew --scan”(goo.gl/UT1Qtb) • そ 他:
https://github.com/gradle/gradle-profiler
ビルドプロセスをプロファイルする • “gradlew clean assembleDebug --profile”
ビルドプロセスをプロファイルする • “gradlew clean assembleDebug --scan”
ビルドプロセスをプロファイルする
結果
1回目 2回目 3回目 4回目 5回目 Before 2 min 37.376 sec
1 min 43.3 sec 1 min 39.9 sec 1 min 37.8 sec 1 min 40.8 sec After 1 min 29 sec 1 min 11 sec 47 sec 46 sec 45 sec
None