How to Accurately Measure and Optimize Android Frame Rate with APM
This article explains how APM provides frame‑rate data for Android, discusses the challenges of inaccurate FPS, introduces metrics such as scroll FPS, frozen‑frame ratio, scrollHitchRate and frame‑cause analysis, details the rendering pipeline, code implementations, optimization techniques, and integration with AB testing for performance improvement.
System Rendering Mechanism
Before implementing metrics, we need to understand Android's rendering pipeline, which includes the measure, layout, and draw phases, VSync timing, and Choreographer callbacks.
Rendering Process
When a view is invalidated, ViewRootImpl.scheduleTraversals registers a callback with the Choreographer. The callback types are INPUT, ANIMATION, TRAVERSAL, and COMMIT. The traversal invokes performMeasure, performLayout, and performDraw. After draw, the data is handed to the RenderThread for GPU processing.
Screen Refresh and Triple Buffering
Android 4.1 introduced VSync and a triple‑buffering mechanism, allowing CPU, GPU, and the display to use separate buffers, which reduces jank but adds a small latency.
Exploring Frame Data
APM provides several metrics for performance monitoring, including scroll FPS, frozen‑frame ratio, scrollHitchRate, and frame‑cause analysis, as well as jank stack traces.
Implementation Details
Various approaches were evaluated: the original APM method that counts draws within one second, Android's debug FPS via ViewRootImpl.trackFPS, Matrix's hook of the Choreographer, and the standard Choreographer.FrameCallback. The final solution uses the FrameCallback to compute FPS and distinguishes user‑initiated scroll frames.
private void draw(boolean fullRedrawNeeded) {
// ...
if (mAttachInfo.mViewScrollChanged) {
mAttachInfo.mViewScrollChanged = false;
mAttachInfo.mTreeObserver.dispatchOnScrollChanged();
}
// ...
mAttachInfo.mTreeObserver.dispatchOnDraw();
// ...
} protected void onScrollChanged(int l, int t, int oldl, int oldt) {
final AttachInfo ai = mAttachInfo;
if (ai != null) {
ai.mViewScrollChanged = true;
}
}Metrics Definitions
Frozen frames are UI frames that take longer than 700 ms to render. Frozen‑frame ratio = (number of frozen frames during scroll) / (total frames generated by scrolling). scrollHitchRate (originating from iOS) measures the proportion of time spent in hitches during a scroll, where a hitch is a frame whose duration exceeds the standard rendering budget.
Frame Cause Analysis
Using Window.OnFrameMetricsAvailableListener (available from Android API 24) we can obtain per‑frame timestamps such as INPUT_HANDLING_DURATION , ANIMATION_DURATION , LAYOUT_MEASURE_DURATION , DRAW_DURATION , SYNC_DURATION , COMMAND_ISSUE_DURATION , SWAP_BUFFERS_DURATION , and TOTAL_DURATION . By comparing these values against a threshold, we can identify the primary cause of a slow frame and target it for optimization.
Jank Stack Collection
Jank stacks are captured via a watchdog that posts a dump request when a frame exceeds a predefined threshold. The collected stacks are then clustered to pinpoint the dominant issue and to drive alerting and remediation.
AB Testing Integration
APM metrics are fed into Alibaba's AB testing platforms (Yixiu, Motu) to compare baseline and optimized buckets, enabling data‑driven performance validation.
Conclusion
Frame‑rate and jank monitoring are essential components of mobile performance engineering. When combined with AB testing, automated alerting, and comprehensive data pipelines, they help maintain a high‑quality user experience across Android applications.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
