Using FrameMetrics to track UI performance - Part 1

Jitin Sharma
2 min readNov 13, 2016

Android Nougat(7.0) introduced a nice feature to get UI performance data at runtime using FrameMetrics. Now this is not a new feature as same can be done using adb shell dumpsys gfxinfo.

FrameMetrics can be useful if you want to track UI performance data in production apps where your environment is expanded over to possibly billion devices, with different OS,RAM,processor etc and one factor unique to each device: The User.

Let’s get on to code.

Initialize a FrameMetrics Listener with handler. A handler is required because you want to listen to events after animations and layout rendering is complete.

FrameMetrics metrics;Handler handler = new Handler();
getWindow().addOnFrameMetricsAvailableListener(new Window.OnFrameMetricsAvailableListener() {
@Override
public void onFrameMetricsAvailable(Window window, FrameMetrics frameMetrics, int i) {
metrics = new FrameMetrics(frameMetrics);
}
}, handler);

Get metrics after a certain delay(customize for yourself)

handler.postDelayed(new Runnable() {
@Override
public void run() {

Log.d("Metrics", "ANIMATION_DURATION: " + metrics.getMetric((FrameMetrics.ANIMATION_DURATION)) / Math.pow(10, 6));
Log.d("Metrics", "COMMAND_ISSUE_DURATION: " + metrics.getMetric(FrameMetrics.COMMAND_ISSUE_DURATION) / Math.pow(10, 6));
Log.d("Metrics", "DRAW_DURATION: " + metrics.getMetric(FrameMetrics.DRAW_DURATION) / Math.pow(10, 6));
Log.d("Metrics", "FIRST_DRAW_FRAME: " + metrics.getMetric(FrameMetrics.FIRST_DRAW_FRAME) / Math.pow(10, 6));
Log.d("Metrics", "INPUT_HANDLING_DURATION: " + metrics.getMetric(FrameMetrics.INPUT_HANDLING_DURATION) / Math.pow(10, 6));
Log.d("Metrics", "LAYOUT_MEASURE_DURATION: " + metrics.getMetric(FrameMetrics.LAYOUT_MEASURE_DURATION) / Math.pow(10, 6));
Log.d("Metrics", "SWAP_BUFFERS_DURATION: " + metrics.getMetric(FrameMetrics.SWAP_BUFFERS_DURATION) / Math.pow(10, 6));
Log.d("Metrics", "SYNC_DURATION: " + metrics.getMetric(FrameMetrics.SYNC_DURATION) / Math.pow(10, 6));
Log.d("Metrics", "TOTAL_DURATION: " + metrics.getMetric(FrameMetrics.TOTAL_DURATION) / Math.pow(10, 6));
Log.d("Metrics", "UNKNOWN_DELAY_DURATION: " + metrics.getMetric(FrameMetrics.UNKNOWN_DELAY_DURATION) / Math.pow(10, 6));

}
}, 2000);

FrameMetrics Listener can be used multiple times within your application to listen for animation durations as well as track layout measuring time for dynamic views.

Here is a sample output(in seconds) with an empty Relative layout running on Nexus 5 emulator with API 24. Complex definitions here

ANIMATION_DURATION: 0.03
COMMAND_ISSUE_DURATION: 34.288
DRAW_DURATION: 0.401
FIRST_DRAW_FRAME: 0.0
INPUT_HANDLING_DURATION: 0.045
LAYOUT_MEASURE_DURATION: 0.425
SWAP_BUFFERS_DURATION: 5.861
SYNC_DURATION: 0.04
TOTAL_DURATION: 47.534289
UNKNOWN_DELAY_DURATION: 5.159289

In part 2, we’ll try to analyze what these values mean and how to best analyze data provided by FrameMetrics.

--

--