whoami-shubham / android-performance-profiler

Profile Android performance even in production on CLI or Flipper plugin

Home Page:https://bamlab.github.io/android-performance-profiler/report/complex-list/s10/report.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Measure the performance of any Android app 🚀

image

Getting started with the automated profiler

  1. Install the profiler
yarn add --dev @perf-profiler/e2e
  1. Create a TS script including a performance test

For instance, here we'll be testing the start up performance of the app for 10 iterations:

// performance.ts
import { execSync } from "child_process";
import { TestCase, measurePerformance } from "@perf-profiler/e2e";

// `npx @perf-profiler/profiler getCurrentApp` will display info for the current app
const bundleId = "com.reactnativefeed";

const stopApp = () => execSync(`adb shell am force-stop ${bundleId}`);
const startApp = () =>
  execSync(
    `adb shell monkey -p ${bundleId} -c android.intent.category.LAUNCHER 1`
  );

const startTestCase: TestCase = {
  duration: 10000,
  beforeTest: () => {
    stopApp();
  },
  run: () => {
    startApp();
  },
};

const test = async () => {
  const { measures, writeResults } = await measurePerformance(
    bundleId,
    startTestCase,
    10
  );
  writeResults();
};

test();
  1. Run your script:
npx ts-node performance.ts
  1. Open the JSON file generated in the web profiler:
npx @perf-profiler/web-reporter results.json

Using Appium

Appium is an e2e testing framework which works with no installation required on your app.
We created @bam.tech/appium-helper to simplify its use and you can use integrate the performance measures like so:

  1. Install
yarn add --dev @perf-profiler/e2e @bam.tech/appium-helper
  1. Create a test file including a performance test
import { AppiumDriver } from "@bam.tech/appium-helper";
import { TestCase, measurePerformance } from "@perf-profiler/e2e";

// `npx @perf-profiler/profiler getCurrentApp` will display info for the current app
const bundleId = "com.reactnativefeed";
const appActivity = `com.reactnativefeed.MainActivity`,

test("e2e", async () => {
  const driver = await AppiumDriver.create({
    appPackage: bundleId,
    appActivity,
  });

  const startApp: TestCase = {
    beforeTest: async () => {
      driver.stopApp();
      await driver.wait(3000);
    },
    run: async () => {
      driver.startApp();
      await driver.findElementByText("As you may");
    },
    duration: 10000,
  };

  const { writeResults } = await measurePerformance(bundleId, startApp);
  writeResults();
});
  1. Run npx appium in one tab
  2. Run yarn jest yourtest in a separate tab
  3. Open the JSON file generated in the web profiler:
npx @perf-profiler/web-reporter results.json

Running in CI

To run in CI, you'll need the CI to be connected to an Android device. An emulator running on the CI will likely be too slow, so it's best to be connected to a device farm cloud. The profiler needs full adb access, so only few device cloud are compatible:

Our choice is AWS Device Farm but some other options should work as well (though they haven't been tested):

  • Saucelabs with Entreprise plan and Virtual USB
  • Genymotion Cloud (using emulators will not accurately reproduce the performance of a real device)

AWS Device Farm

We've added a neat tool to seamlessly run your tests on AWS Device Farm and get the measures back:

export AWS_ACCESS_KEY_ID="ADD YOUR AWS KEY ID HERE" AWS_SECRET_ACCESS_KEY="ADD YOUR AWS SECRET HERE"

# Run from your root folder, containing `node_modules`
npx @perf-profiler/aws-device-farm runTest \
  --apkPath app-release.apk \
  --deviceName "A10s" \
  --testCommand "yarn jest appium"

Flipper Plugin

prod-profiler.mp4

Install

Search for android-performance-profiler in the Flipper marketplaceimage

CLI

You can profile directly in CLI with:

npx @perf-profiler/profiler profile --fps --ram --threadNames "(mqt_js)" "UI Thread"

You can also use a custom script:

Via Custom script

For instance:

import {
  detectCurrentAppBundleId,
  getAverageCpuUsage,
  getPidId,
  Measure,
  pollPerformanceMeasures,
} from "@perf-profiler/profiler";

const { bundleId } = detectCurrentAppBundleId();
const pid = getPidId(bundleId);

const measures: Measure[] = [];

const polling = pollPerformanceMeasures(pid, (measure) => {
  measures.push(measure);
  console.log(`JS Thread CPU Usage: ${measure.perName["(mqt_js)"]}%`);
});

setTimeout(() => {
  polling.stop();
  const averageCpuUsage = getAverageCpuUsage(measures);
  console.log(`Average CPU Usage: ${averageCpuUsage}%`);
}, 10000);

Contributing

web-reporter

At the root of the repo:

yarn
yarn tsc --build --w

and run in another terminal:

yarn workspace @perf-profiler/web-reporter start

Then in packages/web-reporter/src/App.tsx, uncomment the lines to add your own measures:

// Uncomment with when locally testing
// eslint-disable-next-line @typescript-eslint/no-var-requires
testCaseResults = [require("../measures.json")];

You should now be able to open the local server

Run yarn jest Plugin -u after modifications.

About

Profile Android performance even in production on CLI or Flipper plugin

https://bamlab.github.io/android-performance-profiler/report/complex-list/s10/report.html

License:MIT License


Languages

Language:TypeScript 88.3%Language:JavaScript 6.0%Language:C++ 3.8%Language:Shell 1.4%Language:HTML 0.4%Language:CMake 0.1%