I am a front-end developer and I want to monitor webview performance. I have two scenarios:
- Use deeplink to jump directly to my webview page
- Use
pidof MY_PACKAGE_NAME
to get process id - Monitor app's main process's cpu by
top
( previouslyps
, but apparentlytop
is more appropriate ) - Inject or not an endless loop using javascript inside webview
- Cancel the endless loop and calculate the average cpu percentage
The result shows the endless loop case's avg cpu is lower than the no loop one.
This is counter-intuitive, I understand that modern app has multi-process structure, but why on earth endless loop's case has lower cpu.
I am using playwright to connect and send adb
command to communicate with my android device. Below is the result:
{
"loop": {
"avg": 25.7,
"p25": 0,
"p50": 3.5,
"p75": 21.2,
"p80": 65.2,
"p90": 92.8,
"p95": 99.8,
"p99": 190.8,
"max": 306
},
"no-loop": {
"avg": 13.3,
"p25": 0,
"p50": 3.4,
"p75": 7.1,
"p80": 10.3,
"p90": 21,
"p95": 81.3,
"p99": 195.6,
"max": 274
}
}
For those interested in source code, below's the source code written in typescript.
import { _android as android } from "playwright";
const [device] = await android.devices();
await device.shell('am force-stop MY_PACKAGE_NAME');
const url = encodeURIComponent("MY_H5_URL");
const deeplink = `myapp://browser/?url=${url}`;
await device.shell(`am start -a android.intent.action.VIEW -d "${deeplink}"`);
const webview = await device.webView({
pkg: "MY_PACKAGE_NAME:web",
});
const page = await webview.page();
const packagePid = await device.shell(`pidof MY_PACKAGE_NAME`).then(buffer => buffer.toString().trim());
setInterval(async () => {
await device.shell(`top -b -n 1 -d 0.1 -o PID,%CPU,RES -p ${packagePid}`)
// ...Omit the collecting logic for simplicity
}, 1000);
// deliberately run some CPU intensive task in Webview
await page.evaluate(() => {
const startTime = Date.now();
while (Date.now() - startTime < 20_000) { // endless loop for 20 seconds
Math.sqrt(Math.random());
}
});
// Calculate the CPU stats from the top outputs collected
// ...Omit the calculation for simplicity
await device.close();
top
command will produce cpu% more than 100%, which means it will consider multi-core usage. You mean whattop
command produces is meaningless cause cpu core has different types? So is there any workaround to measure a fair cpu percentage considering different cpu core types. Intuitively, intensive webview should have more cpu load than none-intensive one.