Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Relevance of code minification in a performance...

Jitin
September 17, 2022

Relevance of code minification in a performance world - Devfest Bangalore

R8 and Proguard are Android developer's go-to tool for code minification. As a developer, inconsistent proguard rules can affect your application in more ways than you know. This talk will focus on code minification and it's additional impacts, divided into 3 parts
- Small introduction to code obfuscation and minification.
- Introduction to proguard rules, common mistakes and how to avoid them.
- A deep dive on how performance of app is impacted by proguard rules.

Jitin

September 17, 2022
Tweet

More Decks by Jitin

Other Decks in Programming

Transcript

  1. Relevance of code mini fi cation in a performance world

    Jitin Sharma BLR Devfest jitinsharma.com @_jitinsharma Architect, Groww GDE Android
  2. What we’ll discuss • Code obfuscation and mini fi cation

    • Introduction to obfuscation tools • Proguard rules • Performance impacts of code mini fi cation • Common mistakes and how to avoid them
  3. Obfuscation class Repository viewModel.fetchData() fun matchUser() val loggedIn = false

    package com.awesome.app class a c.zz() fun rt() val y = false package com.g.f
  4. Mini fi cation fun main() { fetchUser() } fun fetchUser()

    { fetchProfile() } fun fetchProfile() { displayProfile() } fun displayProfile() { .. } main() fetchUser() fetchProfile() displayProfile()
  5. Mini fi cation fun main() { fetchUser() } fun fetchUser()

    { // fetchProfile() } fun fetchProfile() { displayProfile() } fun displayProfile() { .. } main() fetchUser() fetchProfile() displayProfile()
  6. Mini fi cation fun main() { fetchUser() } fun fetchUser()

    { // fetchProfile() } fun fetchProfile() { displayProfile() } fun displayProfile() { .. } main() fetchUser() fetchProfile() displayProfile()
  7. Android Toolchain Code (source code + libraries) Obfuscation + minification

    D8/R8 minified dex AGP Toolchain (removes unused resources) manifest, resources apk dex/IR
  8. Android Toolchain Code (source code + libraries) dex/IR minified dex

    AGP Toolchain (removes unused resources) manifest, resources ResourceUsageAnalyzer.java apk Obfuscation + minification D8/R8
  9. Rules fun main() { val clazz = Class.forName() val method

    = clazz.getDeclaredMethod() method.invoke() } main() method()
  10. Comparison App Type Size App Launch Mode Non Mini fi

    ed 11.8MB 596.6ms Release Mini fi ed 6.5MB 367.9ms Release Mini fi ed + Shrinked 6.4MB 361.3ms Release
  11. Code Inlining fun myBranchedFunction() { if (BuildConfig.DEBUG) { debugMethod() }

    else { releaseMethod() } } fun myBranchedFunction() { releaseMethod() }
  12. Code Inlining if (Build.VERSION.SDK_INT >= 21) { window.statusBarColor = ..

    } if (Build.VERSION.SDK_INT >= 28) { val displayCutOut = decorView.rootWindowInsets.displayCutout ... } minSdk 19 if (Build.VERSION.SDK_INT >= 21) { window.statusBarColor = .. } if (Build.VERSION.SDK_INT >= 28) { val displayCutOut = decorView.rootWindowInsets.displayCutout ... }
  13. Code Inlining if (Build.VERSION.SDK_INT >= 21) { window.statusBarColor = ..

    } if (Build.VERSION.SDK_INT >= 28) { val displayCutOut = decorView.rootWindowInsets.displayCutout ... } minSdk 21 window.statusBarColor = .. if (Build.VERSION.SDK_INT >= 28) { val displayCutOut = decorView.rootWindowInsets.displayCutout ... }
  14. Code Inlining if (Build.VERSION.SDK_INT >= 21) { window.statusBarColor = ..

    } if (Build.VERSION.SDK_INT >= 28) { val displayCutOut = decorView.rootWindowInsets.displayCutout ... } minSdk 28 window.statusBarColor = .. val displayCutOut = decorView.rootWindowInsets.displayCutout ...
  15. Code Inlining fun trim(String name) { Intrinsics.checkParameterIsNotNull(name) name(…) } fun

    trim(String name) { if (name != null) { name(…) } else { // exception } }
  16. App Startup Non Mini fi ed Mini fi ed Dex

    load: 2.96 ms Dex load: 0.07 ms
  17. Systrace Event Non mini fi ed Mini fi ed Mode

    bindApplication 54.46 ms 19.24 ms Release ResourcesManager#getRes ources 4.62 ms 3.97 ms Release ResourcesImpl#updateCon fi guration 3.98 ms 2.62 ms Release LoadApkAssets 1.3 ms 0.68 ms Release VectorDrawable#in fl ate 0.41 ms 0.39 ms Release
  18. Rules can hurt you - keep class com.mypackage.** - keep

    com.somepackage.R$* - keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
  19. Transitive R classes App Module1 Module2 Module3 Module4 Module5 aar

    aar aar aar R.class R.class R.class R.class R.class R.class R.class R.class R.class
  20. 6.4 mb 361.3 ms Mini fi ed 6.6 mb (+3%)

    487.1 ms (+34%) Mini fi ed with faulty rules
  21. 6.4 mb 361.3 ms Mini fi ed 6.6 mb (+3%)

    487.1 ms (+34%) Mini fi ed with faulty rules Dex Count: 1 Dex Size: 634KB Dex load: 0.07ms Dex Count: 2 Dex Size: 894KB Dex load: 0.09ms
  22. Rules • Be aggressive instead of defensive when de fi

    ning proguard rules. • Avoid wildcard package rules. • Use @Keep to attach rules to codebase instead of rules fi les. • Scan for rules which third party rules are importing in your codebase.