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

Tools to Help You Improve Android App Performance

Tools to Help You Improve Android App Performance

By : Janice Kartika, Product Engineer - Gojek
Live : https://youtu.be/qhkNL0o7x3o?t=4429

Tweet

More Decks by Android Enthusiast Jakarta

Other Decks in Technology

Transcript

  1. Contents 1 Bad and good app performance 2 Basic performance

    test 3 Profile GPU Rendering tool 4 Debug GPU Overdraw and Layout Inspector tool 5 Android (Memory) Profiler tool
  2. Bad and Good App Performance Signs we can see and/or

    feel to determine bad/good app performance
  3. Bad • Takes a long time to load or does

    not load • Stutter animations • App crashes randomly • Slow response to user actions • Drains battery • Use lots of data plan Good • Loads fast • Smooth animations • No crashes • Fast response to user actions • Respects limited battery resources • Optimizes data transmission
  4. Frame Rate • 60 FPS (frames per second) • Appears

    as smooth motion to our eyes • 1000 ms / 60 frames = 16-ish ms for 1 frame • This 16 ms is not only for our app, but Android system also
  5. Steps • (If possible) Install your app on low-end physical

    device. • Try yourself to crash the app + observing performance issue you feel + take notes. • Once done, ask at least 5 other people to do the same. This is a usability testing. • Why 5 people? [link to Jakob Nielsen’s research]
  6. Read the Graph Horizontal green line: 16 ms / frame

    Vertical bar: • Shows time needed to render a frame • Higher = slower • Color codes represent rendering stages each frame • Below green line: frame is rendered less than 16 ms • Above green line: frame is rendered more than 16 ms
  7. Color Codes Draw High blue bar: • Views are invalidated

    • Complex logic inside onDraw method
  8. Color Codes Command Issue High red bar: • Complex custom

    views • Requesting views to be redrawn (not necessarily invalidated) • Calling too many draw operations:
  9. Color Codes Swap Buffers Represents the time the CPU is

    waiting for the GPU to finish its work. High orange bar: • App is doing too much work on GPU • Same optimization as Command Issue phase
  10. Color Codes Sync & Upload The time to upload bitmap

    information from CPU to the GPU. Avoid high blue bar: • Reduce large image size (resizing). • Use prepareToDraw() to pre-upload beforehand.
  11. Color Codes Measure / Layout Measure = calculate the size

    of objects on the screen. Layout = sizing and positioning objects on the screen. High green bar: • Nested layouts (try to optimize view hierarchy) • Check the code inside onMeasure() and onLayout()
  12. Debug GPU Overdraw and Layout Inspector Tool Overdraw = where

    a pixel is redrawn multiple times in a single frame of rendering
  13. Overdraw Color Codes True color → no overdraw → 1x

    → 2x → 3x → 4x or more Normal GPU Overdraw Enabled
  14. Reduce Overdraw • Remove unnecessary, overlapping backgrounds • Flatten view

    hierarchy • Use Layout Inspector tool to help further (debug mode only)
  15. 3D View Layout Inspector • Display UI hierarchy in 3D

    view: rotation mode • Find this button (hope it’s enabled for you): • Available from API 29 and above • GIF source
  16. Android Memory 101 • Memory allocation → reserve memory for

    our app’s objects, processes, services in the assigned memory heap. • The used memory can be reclaimed when objects are no longer accessible (no reference to the objects). Garbage collector will do the work. • Too many temporary objects created by our code can pollute the memory heap → indirectly trigger multiple garbage collection events → degrade overall performance. • When the memory can’t be reclaimed because the reference to the objects are never released → memory leak. • Less and less memory slows down the app, eventually app would crash when no memory left available (last resort to free up memory).
  17. Be Friendly with Memory • NEVER reference view objects outside

    UI thread or from static objects, avoid leaks. • Avoid allocating objects in inner loops to prevent too many garbage collection events. • Avoid allocating objects in onDraw() methods as this method is called 60 times per second (to achieve the smoothness 60 FPS). • Example:
  18. Example Memory-Inefficient App • Image Source link • Increased memory

    over time • GC is performed but the decreased is less than the increased • Eventually app crashed
  19. Dump and Inspect Heap • Snapshot of allocated memory at

    specific point in time. • Allocations: number of instance of that class in memory. • Shallow Size: total size of all instances of that class. • Retained Size: its shallow size plus the shallow sizes of the objects that are accessible from that class.
  20. Dump and Inspect Heap • Depth: shortest number of hops

    from any GC root to the selected instance. • Shallow Size: size of the instance. • Retained Size: total size of memory being retained due to all instances in that class.
  21. Case Study: Gojek • Not all views are required to

    be initialised because user may not need it at runtime. • Lazy initialization can be a solution. • Only create instance of views that user really needs to see.
  22. Bonus: System Tracing • Enable from developer mode. • Record

    trace of your app. • The .perfetto-trace or .ctrace file will be generated. • Use Perfetto UI to open the file.
  23. Know What You Want to Know • I know from

    Profile GPU Rendering that a custom view is causing slow frame rendering. • Looks like the issue also exists in CPU rendering pipeline. • Using systrace, I want to know the time needed to execute draw method of that custom view.
  24. We Can Use CPU Profiler, Right??? • Yes we can.

    • Sometimes profiler causes the app to be much more laggy than usual → affects the profiler result. • Link to related article by Paulina Sadowska.