Slide 1

Slide 1 text

Android Performance for Dummies ( & Experts)

Slide 2

Slide 2 text

Introduction

Slide 3

Slide 3 text

CleverTap combines real-time customer insights, an advanced segmentation engine, and powerful engagement tools into one intelligent marketing platform. At CleverTap, we process over 10 billion data points and send over 2 billion communications every day. And, we can deliver over 20 million push notifications in under a minute. CleverTap helps you build valuable, long-term relationships with your customers by giving you access to real-time behavioral analytics so you know who they are, and a platform with which you can engage users on the right channels, at the right time, and with a message that resonates. What does do?

Slide 4

Slide 4 text

Performance issues

Slide 5

Slide 5 text

How many times have you measured your start-up times to improve your app?

Slide 6

Slide 6 text

Do you check out the size and contents of third party libraries before including them in your project?

Slide 7

Slide 7 text

Have your users complained that your app is crashing or draining their battery or is very slow?

Slide 8

Slide 8 text

Does your app take a lot of time to build or does your layout take a considerable time to render, and you do not know why that is happening?

Slide 9

Slide 9 text

Android Vitals

Slide 10

Slide 10 text

Android Vitals Android Vitals is like a suite provided as a part of the Google Play Store which gives Android developers a basic overview on their App's overall performance.

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Crashes Crashes are pretty straightforward. A runtime exception leads to crashes.

Slide 14

Slide 14 text

ANRs ANRs are more annoying and tricky to solve. The easiest explanation is this - any task which is async but runs on the main thread will lead to an ANR.

Slide 15

Slide 15 text

Reduce APK Size

Slide 16

Slide 16 text

1% For every 6 MB increment in size, the install conversion rate could drop by 70% of users in a poll mentioned that storage is a crucial parameter in deciding between a similar functional application App Installations

Slide 17

Slide 17 text

App Uninstallations 1 in every 4th App Uninstall is driven by lack of space on device

Slide 18

Slide 18 text

Reduce Apk Size 1. Shrink 2. Optimize 3. Obfuscate

Slide 19

Slide 19 text

Code shrinking - detects and safely removes unused classes, fields, methods, and attributes from your app and its library dependencies Famous 64K Limit Fun fact for beginners : Code shrinking with R8 is enabled by default when you set the minifyEnabled property to true. So you might be using R8 already without ever knowing about it. Reduce Apk Size R8 Compiler 1. Shrink your code

Slide 20

Slide 20 text

We have shrunk our code. But there is so much more scope of Optimization which R8 helps us achieve. 1. Dead-code: With this technique, we can remove the code that’s unreachable — like sometimes there will be code in the if condition that’s always false. Unreachable statements. 2. Unused-arguments: Removes unused arguments in the method or class constructor. 3. In-lining: Removes selective classes and include their functionality in-line, when it’s required. Say, if your code calls a method in only one place, R8 might remove the method and inline it at the single call site. Reduce Apk Size R8 Compiler 1. Shrink 2. Optimize

Slide 21

Slide 21 text

The purpose of obfuscation is to reduce your app size by shortening the names of your app’s classes, methods, and fields. In simple words, shorten names and squash packages. Reduce Apk Size R8 Compiler 1. Shrink 2. Optimize 3. Obfuscate It helps 1. Saves file sizes with help of DEX files w.r.t reducing references of many classes, methods, and fields. 2. Making decompiling application hard. Since it is not human -readable without mapping file.

Slide 22

Slide 22 text

So, we have now improved our code, but resources are still the major problem. Reduce Apk Size Shrink Resources Do we have to do this manually for everyone? ShrinkResources ON. Unused Resources GONE. Warning! : in default mode, this would not work if your code makes a call to Resources.getIdentifier() Use Android Lint to Identify unused resources.

Slide 23

Slide 23 text

Pro-tip : If you are using Google Play console for distribution, you should build and upload an Android App Bundle. With this, it automatically generates and serves optimized APKs for each configuration, so they download only the code and resources they need to run your app. Reduce Apk Size Split Apks

Slide 24

Slide 24 text

1. Use APK Size Analyzer to identify biggest culprits Reduce Apk Size More hacks 2. Reuse resources.

Slide 25

Slide 25 text

3. Image Optimizations. WebP & VectorDrawables. PNG : True color vs Indexed Format Reduce Apk Size Hacks Indexed 8 bit Original True color 196 KB 42 KB

Slide 26

Slide 26 text

5. Downloadable Fonts Reduce Apk Size Hacks 6. Android App Bundles

Slide 27

Slide 27 text

Android Profiling

Slide 28

Slide 28 text

CPU Profiling System Trace: Captures fine-grained details that allow you to inspect how your app interacts with system resources. Method and function traces: For each thread in your app process, you can find out which methods (Java) or functions (C/C++) are executed over a period of time and the CPU resources each method or function consumes during its execution.

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Types of CPU Profiling ● Sample JAVA methods ● Trace JAVA methods ● Sample C/C++ methods ● Trace System Calls ● Top Down ● Flame Chart ● Bottom Up

Slide 31

Slide 31 text

Top Down

Slide 32

Slide 32 text

Bottom Up

Slide 33

Slide 33 text

System trace with CPU cores

Slide 34

Slide 34 text

GPU Rendering

Slide 35

Slide 35 text

Users would kill the app if it failed to start in 5 secs 2 in every 5

Slide 36

Slide 36 text

GPU Rendering Most common confusion everyone faces is CPU vs GPU How do we compute? Take example of making a DB call, to fetch list of items and display the list. DB call and COMPUTING the list of items is CPU responsibility. Rendering the image is GPU’s responsibility CPU vs GPU

Slide 37

Slide 37 text

GPU Rendering Magic Number - 60 FPS So what this effectively boils down to, is you should have JUST ~ 16 ms to work on each frame. If you are not, the users would notice the lag.

Slide 38

Slide 38 text

GPU Rendering

Slide 39

Slide 39 text

GPU Rendering Key to fast rendering, is to enable your Hardware to spend as much as less time drawing. Good thumb rule to avoid drawing areas which are not going to be seen. Use developer tools -> Debug GPU Overdraw True color: No overdraw Blue : Overdrawn 1 time Green : Overdrawn 2 times Pink : Overdrawn 3 times Red : Overdrawn 4 or more times

Slide 40

Slide 40 text

GPU Rendering Now a days, this is not a problem with the lower specs devices, pushing towards better processing unit. But a good rule of thumb is 1. Avoid complex layouts 2. Flatten view hierarchy and avoid Taxation. 3. Avoid unused backgrounds Make Layout Inspector tool your friend here.

Slide 41

Slide 41 text

GPU Rendering Android GPU Inspector Out in Limited Developer Preview Beta last month. Strongly recommend it for gaming apps. Very Similar to Systrace, it shows a timeline of events for your running game or app, which includes system activities, high frequency GPU hardware counters, and, if you are using Vulkan, GPU activity information

Slide 42

Slide 42 text

Benchmarking

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

How do you measure the code? somework() { long timeStarted = System.currentTimeMillis(); long timeTaken = System.currentTimeMillis() - timeStarted; } doWork(); But is this correct approach for consistent measuring?

Slide 45

Slide 45 text

How do you measure the code? somework() { long timeStarted = System.currentTimeMillis(); long timeTaken = ((System.currentTimeMillis() - timeStarted )/ tests; } doWork(); for i in tests: int tests = 10; Okay ? So is this correct and consistent? What are we missing here?

Slide 46

Slide 46 text

Benchmarking is HARD 1. Defining the magic numbers. How much less is less and how much more is more? 2. Hot code - Warmup. JIT’ed 3. CPU inconsistencies 4. Foreground activities running 5. Hardware changes

Slide 47

Slide 47 text

How do you use Jetpack Benchmark in the code? somework() { } doWork(); @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); final BenchmarkState state = benchmarkRule.getState(); while(state.keepRunning()){ }

Slide 48

Slide 48 text

UI Tests

Slide 49

Slide 49 text

“Each Step matters” 1.01^365 = 37.8 0.99 ^ 365 = 0.03

Slide 50

Slide 50 text

What gets measured, gets improved!

Slide 51

Slide 51 text

Thanks! For your attention. Here’s a picture of Groot. We are Grooting for you, team! Speakers Bhavita Lalwani Senior Software Engineer, Platform @bhavita8, Darshan Pania Android Lead - @i_m_Pania