Slide 1

Slide 1 text

Generating Efficient APK by Reducing Size & Improving Performance

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

When registration started Source:

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

@pareshmayani

Slide 7

Slide 7 text

Smart Phones Ecosystem

Slide 8

Slide 8 text

Limited Battery

Slide 9

Slide 9 text

Limited Battery Limited Storage

Slide 10

Slide 10 text

Limited Battery Limited Storage Limited RAM

Slide 11

Slide 11 text

Limited Battery Limited Storage Limited RAM Limited processing power

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Why Apk size is important?

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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/

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

What goes inside apk Let’s Analyse using Apk Analyser

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Assumption We all follow at least some optimisations

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Raw File size: Actual size of the apk file

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

assets: Contains the app's assets like fonts

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

AndroidManifest.xml: Contains the core Android manifest file

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

1. Reduce ‘res’ count & size

Slide 40

Slide 40 text

Remove unused resources Analyse -> Inspect code...

Slide 41

Slide 41 text

[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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

[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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

[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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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);

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

Vector Asset Studio

Slide 52

Slide 52 text

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 } }

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

Optimise PNG images - ImageOptim

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

2. Reduce ‘assets’ size

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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.

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

Reduce ‘dex’ count & size

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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" } ... ... } }

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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 (*)

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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" } }

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

Reduce native ‘libs’ code

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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' } } }

Slide 74

Slide 74 text

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 } } }

Slide 75

Slide 75 text

Total Savings ??

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

No Questions!!

Slide 80

Slide 80 text

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