flashlight
flashlight copied to clipboard
📱⚡️ Lighthouse for Mobile - audits your app and gives a performance score to your Android apps (native, React Native, Flutter..). Measure performance on CLI, E2E tests, CI...
Measure the performance of any Android app 🚀
- 🙅 No installation required, supports even production app
- ✨ Generates beautiful web report (like this Flatlist/Flashlist comparison)
- 💻 Via CLI, e2e test or Flipper plugin

- Getting started with the automated profiler
- Using Appium
-
Running in CI
- AWS Device Farm
-
Flipper Plugin
- Install
- CLI
- Getting FPS Data
-
Contributing
- web-reporter
Getting started with the automated profiler
- Install the profiler
yarn add --dev @perf-profiler/e2e @perf-profiler/web-reporter
- Create a test file including a performance test
For instance, here we'll be testing the start up performance of the app for 10 iterations:
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 appActivity = `${bundleId}.MainActivity`;
const stopApp = () => execSync(`adb shell am force-stop ${bundleId}`);
const startApp = () =>
execSync(`adb shell am start ${bundleId}/${appActivity}`);
const startTestCase: TestCase = {
duration: 10000,
beforeTest: () => {
stopApp();
},
run: () => {
startApp();
},
};
const test = async () => {
const { measures, writeResults } = await measurePerformance(
bundleId,
startTestCase,
10
);
writeResults();
};
test();
- Open the JSON file generated in the web profiler:
yarn generate-performance-web-report 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:
- Install
yarn add --dev @perf-profiler/e2e @perf-profiler/web-reporter @bam.tech/appium-helper
- 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();
});
- Run
npx appium
in one tab - Run
yarn jest yourtest
in a separate tab - Open the JSON file generated in the web profiler:
yarn generate-performance-web-report 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 $TEST_FOLDER_NAME/apks/$APK_NAME.apk \
--deviceName "A10s" \
--testCommand "yarn jest appium"
Flipper Plugin
https://user-images.githubusercontent.com/4534323/164205504-e07f4a93-25c1-4c14-82f3-5854ae11af8e.mp4
Install
Search for android-performance-profiler
in the Flipper marketplace
CLI
Multiple commands are also available in the standalone package android-performance-profiler
.
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);
Getting FPS Data
FPS debug should be enabled automatically when you run a test. If it doesn't work on your device, follow the steps below:
In developer options, you need to set Profile HWUI rendering to In adb shell dumpsys gfxinfo

Note that this method of recording FPS supports only Native (including RN) apps.
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.