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

The subtle art of making a product lightening fast

The subtle art of making a product lightening fast

Abid Jamil

January 04, 2023
Tweet

More Decks by Abid Jamil

Other Decks in Programming

Transcript

  1. 60% Speed, design & usability When leaving a 5 star

    review, 60% of the time the user mentions the speed, design or usability Google analysis on Play reviews, top 10 English speaking countries, last 365 days of reviews
  2. Firebase Performance Monitoring • Runs in production • Negligible overhead

    • Automatic and Custom traces • Automatic HTTP/S traffic metrics
  3. Trace • A report for a period of time with

    a well-defined beginning and end • Nominally has a duration • Also may contain "counters" for performance-related events during the trace
  4. Automatic Traces -no coding necessary! • App Start (cold) •

    Time in foreground • Time in background
  5. Counters • Associate a string/count value to a Trace •

    Typically better to measure ratios than absolute values • Abs value if you want to compare similar counters between traces cache_hit++ cache_miss++ dropped_frames += 10
  6. Implement Lifecycle Callbacks public class PerfLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { private

    static final PerfLifecycleCallbacks instance = new PerfLifecycleCallbacks(); private PerfLifecycleCallbacks() {} public static PerfLifecycleCallbacks getInstance() { return instance; } }
  7. Implement Lifecyclecallbacks private final HashMap<Activity, Trace> traces = new HashMap<>();

    @Override public void onActivityStarted(Activity activity) { String name = activity.getClass().getSimpleName(); Trace trace = FirebasePerformance.startTrace(name); traces.put(activity, trace); } @Override public void onActivityStopped(Activity activity) { Trace trace = traces.remove(activity); trace.stop(); }
  8. Use Annotations import com.google.firebase.perf.FirebasePerformance; import com.google.firebase.perf.metrics.AddTrace; // Add the `@AddTrace`

    annotation above the method you want to trace @AddTrace(name = "onCreateTrace", enabled = true /* optional */) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) }
  9. Use Annotations val cache = ItemCache() val myTrace = Firebase.performance.newTrace("test_trace")

    myTrace.start() val item = cache.fetch("item") if (item != null) { myTrace.incrementMetric("item_cache_hit", 1) } else { myTrace.incrementMetric("item_cache_miss", 1) }
  10. Android Vitals -get clues for what to measure • New

    in the Google Play Console: • Performance-related stats • Slow rendering (jank) • Frozen frames
  11. Automatic HTTP/S transaction metrics • Response time • Payload size

    • Success rate • URL pattern yourcdn.com/*.jpg api.yourdomain.com/v1/users/* api.yourdomain.com/v1/users/*/history/*
  12. HTTP/S transaction metrics breakdown • App version • Device •

    Country • OS level • Carrier • Radio
  13. How HTTP/S monitoring works Bytecode manipulation (with ASM) URL url

    = new URL("https://firebase.google.com"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); URL url = new URL(“https://firebase.google.com”); HttpsURLConnection conn = (HttpsURLConnection) FirebasePerfUrlConnection.instrument(url.openConnection()); Decorator inside!
  14. How HTTP/S monitoring works dependencies { compile 'com.google.firebase:firebase-perf:11.0.2' } apply

    plugin: 'com.google.firebase.firebase-perf' Uses the Transform API
  15. Implementation • Improve Cold Startup time - Lazy Initialization •

    Don’t save token in shared preferences • Use Caching Strategy • Image Lazy Loading - Use Thumbnails where applicable • Use Relevant Size of Images • Calculations on separate threads • Splash Screen Library • Monitor the Slow and Frozen Frames • Don’t Use Nested Views more than 4 levels