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

Generating Efficient APK by Reducing Size & Improving Performance

Paresh Mayani
November 05, 2017

Generating Efficient APK by Reducing Size & Improving Performance

Talk delivered in GDG Ahmedabad DevFest 2017 (#DevFestAhm) on 5th November, 2017.

Talked about various tips/tricks and steps to reduce apk size. Also covered some of the tools that I have used for reducing apk size.

Enjoy actual presentation with GIFs http://bit.ly/reduce-apk-size-drive

Paresh Mayani

November 05, 2017
Tweet

More Decks by Paresh Mayani

Other Decks in Technology

Transcript

  1. Generating Efficient APK
    by Reducing Size & Improving Performance

    View Slide

  2. Slides
    Slides:
    ● Presentation with GIFs: http://bit.ly/reduce-apk-size-drive
    ● Speakerdeck: http://bit.ly/reduce-apk-size

    View Slide

  3. When we announced #DevFestAhm
    Source: https://media.giphy.com/media/11sBLVxNs7v6WA/giphy.gif

    View Slide

  4. When registration started
    Source:

    View Slide

  5. Thank You all for coming for my session
    Source: https://media.giphy.com/media/10Shl99Vghh5aU/giphy.gif

    View Slide

  6. @pareshmayani

    View Slide

  7. Smart Phones Ecosystem

    View Slide

  8. Limited Battery

    View Slide

  9. Limited Battery
    Limited Storage

    View Slide

  10. Limited Battery
    Limited Storage
    Limited RAM

    View Slide

  11. Limited Battery
    Limited Storage
    Limited RAM
    Limited processing power

    View Slide

  12. Limited Battery
    Limited Storage
    Limited RAM
    Limited processing power
    Limited Data/Network Connectivity

    View Slide

  13. Limited Battery
    Limited Storage
    Limited RAM
    Limited processing power
    Limited Data/Network Connectivity
    Billion Users

    View Slide

  14. Why Apk size is important?

    View Slide

  15. Those big and bloated apk...
    Source: https://media.giphy.com

    View Slide

  16. And when you can’t use such big apk
    That moment when apk is
    crashing
    Waste of user’s time
    Waste of user’s data pack
    Source: https://media.giphy.com

    View Slide

  17. Because everyone doesn’t have OnePlus
    Source: https://media.giphy.com/media/l0MYQgkYlybdCYD3a/giphy.gif

    View Slide

  18. Why apk size is important?
    1. Internet connectivity
    2. Device specifications
    3. Billion Users: To get your next billion users

    View Slide

  19. 1. Internet Connectivity
    Limited internet connectivity (In growing countries like India)
    Limited data pack/plan
    Costly data plan (Each bytes affects user’s wallet)
    Large app size causes longer time to download
    All users don’t have good internet bandwidth/connectivity

    View Slide

  20. The Average Internet Speed In India: Steady Progress
    Source: https://dazeinfo.com/2017/06/02/india-internet-speed-growth-q1-2017/

    View Slide

  21. Good news: 4G is getting rolled out in India
    Source: https://media.giphy.com

    View Slide

  22. 2. Device specifications
    Device specification includes: Storage , Battery, RAM, Processing Power
    Low/Mid range devices have 8GB/16GB storage
    Low/Mid range devices have 1GB/2GB RAM
    Lesser the storage your app uses, user can enjoy more apps and can store more
    pictures/videos
    All users don’t have higher specification devices

    View Slide

  23. Google IO 2017 - Points
    > 100M users came online in 2016
    1B 2G devices expected in 2020
    50% of India is on 2G
    33% users run out of storage in India every day
    Data is expensive – it costs ~$2 to download a 40MB free app in India
    Source: Google IO 2017 & https://ashishb.net/tech/google-io-2017-android-notes/

    View Slide

  24. Apk size has an impact on
    How fast your app loads
    How much memory it uses
    How much power it consumes

    View Slide

  25. What goes inside apk
    Let’s Analyse using Apk Analyser

    View Slide

  26. Case Study
    Let’s take my any project
    P.S. It’s already partially optimised

    View Slide

  27. Assumption
    We all follow at least
    some optimisations

    View Slide

  28. View Slide

  29. Raw File size: Actual size of the apk file

    View Slide

  30. Download size: Estimated size of file for the new installations
    (Google play store server highly optimised file)

    View Slide

  31. res: contains all the resources files like images, menus, layouts, etc.
    (those resources which aren’t compiled into resources.arsc)

    View Slide

  32. assets: Contains the app's assets like fonts

    View Slide

  33. classes.dex: dex file which contains all the byte code files of your java code
    that will run on Dalvik/ART virtual machine

    View Slide

  34. lib: Contains the compiled code that is specific to the software layer of a
    processor.

    View Slide

  35. resources.arsc: Contains compiled resources. Contains the XML content
    from all configurations of the res/values/ folder.

    View Slide

  36. META-INF: Contains the CERT.SF and CERT.RSA signature files, as well as
    the MANIFEST.MF manifest file

    View Slide

  37. AndroidManifest.xml: Contains the core Android manifest file

    View Slide

  38. Files to concentrate on
    res + assets + classes.dex + lib + resources.arsc = 98.7%

    View Slide

  39. 1. Reduce ‘res’ count & size

    View Slide

  40. Remove unused resources
    Analyse -> Inspect code...

    View Slide

  41. [Result] Remove unused resources
    `res` Reduction => 54.9% to 48.1% = Total 6.8% reduction
    Raw File Size => 24.1 MB to 21.9 MB = -2.2 MB
    Download Size => 21.8 MB to 19.7 MB = -2.1 MB

    View Slide

  42. Shrinking resources
    android {
    buildTypes {
    release {
    minifyEnabled true
    shrinkResources true
    }
    }

    View Slide

  43. [Result] Shrinking resources
    `res` Reduction => 48.1% to 46.3% = Total 1.8% reduction
    Raw File Size => 21.9 MB to 21.2 MB = -0.7 MB
    Download Size => 19.7 MB to 19 MB = -0.7 MB

    View Slide

  44. Exclude Sparse Translation
    android {
    defaultConfig {
    resConfigs "en", "fr"
    }
    }

    View Slide

  45. [Result] Exclude Sparse Translation
    Raw File Size => 21.2 MB to 20.5 MB = -0.7 MB
    Download Size => 19 MB to 18.9 MB = -0.1 MB

    View Slide

  46. Reusing resources
    Scenario: ic_arrow_collapse & ic_arrow_expand
    Include only one set of icons
    Create RotateDrawable for another

    android:drawable="@drawable/ic_arrow_expand"
    android:fromDegrees="180"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="180" />

    View Slide

  47. Reusing resources - setColorFilter
    Include only one set of icons
    Apply color filter
    PorterDuff.Mode mMode = PorterDuff.Mode.SRC_ATOP;
    Drawable d = getResources().getDrawable(R.drawable.ic_tier_pressure_fluid);
    d.setColorFilter(ContextCompat.getColor(this, R.color.colorAccent),mMode);

    View Slide

  48. Shape Drawables
    Using XML, you can create simple set of shapes
    Occupies less memory than actual images


    android:width="5dp"
    android:color="#D8FDFB" />
    android:bottom="7dp"
    android:left="7dp"
    android:right="7dp"
    android:top="7dp" />



    View Slide

  49. View Slide

  50. Vector Drawables
    Based on Vector Graphics
    Scaled without loss of display quality, means same file is resized for different
    screen densities without loss of image quality
    VectorDrawable & VectorDrawableCompat
    AnimatedVectorDrawable & AnimatedVectorDrawableCompat

    View Slide

  51. Vector Asset Studio

    View Slide

  52. Crunch PNG files
    aapt tool can optimize the image resources placed in res/drawable/ with
    lossless compression
    can convert a true color PNG that does not require more than 256 colors to an
    8-bit PNG with a color palette.
    With Android plugin for Gradle 3.0.0 , AAPT2 is now enabled by default.
    android {
    aaptOptions {
    cruncherEnabled true
    }
    }

    View Slide

  53. Optimise PNG images
    Command Utility tools PngCrush, pngquant for Lossy compression
    Pngquant has a GUI tool - ImageOptim for Mac

    View Slide

  54. Optimise PNG images - ImageOptim

    View Slide

  55. Optimise video files
    HD Quality videos are not required for mobile apps
    Compress it using tools available over web

    View Slide

  56. Step 1 - Result
    Raw File Size => 24.1 MB to 17.3 MB = -6.8 MB
    Download Size => 21.8 MB to 15.7 MB = -6.1 MB

    View Slide

  57. 2. Reduce ‘assets’ size

    View Slide

  58. Use downloadable fonts
    Remove font files from ‘assets’ folder
    Use downloadable fonts

    View Slide

  59. How does Downloadable font works
    A font provider is an application that retrieves fonts and caches them locally so
    other apps can request and share fonts.

    View Slide

  60. Step 2 - Result
    Raw File Size => 17.3 MB to 14.6 MB = -2.7 MB
    Download Size => 15.7 MB to 13 MB = -2.7 MB

    View Slide

  61. Reduce ‘dex’ count & size

    View Slide

  62. Minifying code
    android {
    buildTypes {
    release {
    minifyEnabled true
    shrinkResources true
    }
    }
    }

    View Slide

  63. Proguard
    buildTypes {
    release {
    minifyEnabled true
    shrinkResources true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    proguardFile "$project.rootDir/settings/proguard_files/proguard-square-okhttp3.pro"
    proguardFile "$project.rootDir/settings/proguard_files/proguard-google-play-services.pro"
    proguardFile "$project.rootDir/settings/proguard_files/proguard-okio.pro"
    proguardFile "$project.rootDir/settings/proguard_files/proguard-crashlytics.pro"
    proguardFile "$project.rootDir/settings/proguard_files/proguard-gson.pro"
    }
    ...
    ...
    }
    }

    View Slide

  64. Analyze and maintain dependencies
    You never know which sdk/libraries includes what dependencies
    ./gradlew app:dependencies

    View Slide

  65. Analyse dependencies
    +--- com.android.support:design:26.1.0
    | +--- com.android.support:support-v4:26.1.0
    | | +--- com.android.support:support-compat:26.1.0
    | | | +--- com.android.support:support-annotations:26.1.0
    | | | \--- android.arch.lifecycle:runtime:1.0.0
    | | | +--- android.arch.lifecycle:common:1.0.0
    | | | | \--- com.android.support:support-annotations:26.1.0
    | | | +--- android.arch.core:common:1.0.0
    | | | | \--- com.android.support:support-annotations:26.1.0
    | | | \--- com.android.support:support-annotations:26.1.0
    | | +--- com.android.support:support-media-compat:26.1.0
    | | | +--- com.android.support:support-annotations:26.1.0
    | | | \--- com.android.support:support-compat:26.1.0 (*)
    | | +--- com.android.support:support-core-utils:26.1.0
    | | | +--- com.android.support:support-annotations:26.1.0
    | | | \--- com.android.support:support-compat:26.1.0 (*)
    | | +--- com.android.support:support-core-ui:26.1.0
    | | | +--- com.android.support:support-annotations:26.1.0
    | | | \--- com.android.support:support-compat:26.1.0 (*)
    | | \--- com.android.support:support-fragment:26.1.0
    | | +--- com.android.support:support-compat:26.1.0 (*)
    | | +--- com.android.support:support-core-ui:26.1.0 (*)
    | | \--- com.android.support:support-core-utils:26.1.0 (*)

    View Slide

  66. Analyze and maintain dependencies
    Exclude repetitive dependencies
    Benefits:
    ● Can avoid version conflicts
    ● Can avoid multiple copy of same sdk

    View Slide

  67. Analyze and maintain dependencies
    dependencies {
    ...
    ...
    compile('co.adcel.android:adcel:1.2.1') {
    exclude group: "com.google.android.gms"
    // exclude group: "com.startapp.android"
    // exclude group: "com.personagraph"
    exclude group: "com.flurry"
    exclude group: "com.android.support"
    }
    compile ("jp.wasabeef:recyclerview-animators:2.2.6") {
    exclude group: "com.android.support"
    }
    }

    View Slide

  68. Google play services
    Include only required sub-sdks from Google play service
    compile 'com.google.android.gms:play-services-gcm:' + rootProject.ext.PLAY_SERVICE_LIB_VERSION
    compile 'com.google.android.gms:play-services-location:' + rootProject.ext.PLAY_SERVICE_LIB_VERSION
    compile 'com.google.android.gms:play-services-maps:' + rootProject.ext.PLAY_SERVICE_LIB_VERSION
    compile 'com.google.android.gms:play-services-places:' + rootProject.ext.PLAY_SERVICE_LIB_VERSION
    compile 'com.google.android.gms:play-services-ads:' + rootProject.ext.PLAY_SERVICE_LIB_VERSION

    View Slide

  69. Reduce native ‘libs’ code

    View Slide

  70. Remove deprecated httpclient jars
    Remove legacy jars
    ● Httpclient-4.5.2.jar
    ● Httpcore-4.4.4.jar
    useLibrary 'org.apache.http.legacy'

    View Slide

  71. [Result] Remove deprecated httpclient jars
    Raw File Size => 14.6 MB to 14.5 MB = -0.1 MB

    View Slide

  72. Splitting apks
    Configure multiple apks for different densities
    Configure multiple apks for different CPU architecture (ABI)

    View Slide

  73. Configure multiple apks for densities
    android {
    ...
    splits {
    // Configures multiple APKs based on screen density.
    density {
    // Configures multiple APKs based on screen density.
    enable true
    // Specifies a list of screen densities Gradle should not create multiple APKs for.
    exclude "ldpi", "xxhdpi", "xxxhdpi"
    // Specifies a list of compatible screen size settings for the manifest.
    compatibleScreens 'small', 'normal', 'large', 'xlarge'
    }
    }
    }

    View Slide

  74. Configure multiple apks for ABIs
    android {
    ...
    splits {
    // Configures multiple APKs based on ABI.
    abi {
    // Enables building multiple APKs per ABI.
    enable true
    // By default all ABIs are included, so use reset() and include to specify that we only
    // want APKs for x86, armeabi-v7a, and mips.
    // Resets the list of ABIs that Gradle should create APKs for to none.
    reset()
    // Specifies a list of ABIs that Gradle should create APKs for.
    include "x86", "armeabi-v7a", "mips"
    // Specifies that we do not want to also generate a universal APK that includes all ABIs.
    universalApk false
    }
    }
    }

    View Slide

  75. Total Savings ??

    View Slide

  76. Total Savings
    Raw File Size => 24.1 MB to 14.5 MB = -9.4 MB
    Download Size => 21.8 MB to 13 MB = -8.8 MB
    Notes:
    ● Splitting is not applied yet
    ● This was already partially optimised, as all devs used to follow at least some optimisations

    View Slide

  77. Remember
    Lesser is always better
    Less number of files = low maintenance time
    Less number of files = reduced apk size = faster loading time
    Lesser the apk size = faster the download time
    Less number of files = faster building time

    View Slide

  78. +PareshMayani
    @pareshmayani
    Technical Lead - Android @ Simform
    Manager, GDG Ahmedabad

    View Slide

  79. No Questions!!

    View Slide

  80. Thank You!
    Paresh Mayani
    @pareshmayani
    Slides:
    ● Presentation with GIFs: http://bit.ly/reduce-apk-size-drive
    ● Speakerdeck: http://bit.ly/reduce-apk-size

    View Slide