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. 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
  2. Why apk size is important? 1. Internet connectivity 2. Device

    specifications 3. Billion Users: To get your next billion users
  3. 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
  4. 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
  5. 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/
  6. Apk size has an impact on How fast your app

    loads How much memory it uses How much power it consumes
  7. Download size: Estimated size of file for the new installations

    (Google play store server highly optimised file)
  8. res: contains all the resources files like images, menus, layouts,

    etc. (those resources which aren’t compiled into resources.arsc)
  9. classes.dex: dex file which contains all the byte code files

    of your java code that will run on Dalvik/ART virtual machine
  10. [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
  11. [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
  12. [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
  13. Reusing resources Scenario: ic_arrow_collapse & ic_arrow_expand Include only one set

    of icons Create RotateDrawable for another <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_arrow_expand" android:fromDegrees="180" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" />
  14. 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);
  15. Shape Drawables Using XML, you can create simple set of

    shapes Occupies less memory than actual images <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <stroke android:width="5dp" android:color="#D8FDFB" /> <padding android:bottom="7dp" android:left="7dp" android:right="7dp" android:top="7dp" /> <corners android:radius="4dp" /> <solid android:color="#f0456000" /> </shape>
  16. 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
  17. 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 } }
  18. Optimise PNG images Command Utility tools PngCrush, pngquant for Lossy

    compression Pngquant has a GUI tool - ImageOptim for Mac
  19. Optimise video files HD Quality videos are not required for

    mobile apps Compress it using tools available over web
  20. 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
  21. 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.
  22. 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
  23. 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" } ... ... } }
  24. 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 (*)
  25. Analyze and maintain dependencies Exclude repetitive dependencies Benefits: • Can

    avoid version conflicts • Can avoid multiple copy of same sdk
  26. 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" } }
  27. 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
  28. Remove deprecated httpclient jars Remove legacy jars • Httpclient-4.5.2.jar •

    Httpcore-4.4.4.jar useLibrary 'org.apache.http.legacy'
  29. 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' } } }
  30. 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 } } }
  31. 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
  32. 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
  33. Thank You! Paresh Mayani @pareshmayani Slides: • Presentation with GIFs:

    http://bit.ly/reduce-apk-size-drive • Speakerdeck: http://bit.ly/reduce-apk-size