Performance & Crash Debugging

Android Jank: Find the Long Frame Before Changing Layouts

Jank is a missed frame deadline, not simply a large layout file. Find the work that made a particular frame late before replacing UI components or adding broad caching.

By , FounderUpdated 3 min read

Use the device's actual frame context

The rendering guide explains frame performance. The often-quoted 16.7 ms budget corresponds to 60 Hz; higher refresh rates have shorter frame intervals. A single fixed budget does not describe every device mode.

Measure the interaction users notice: scrolling, a transition, dragging an object or opening a complex screen.

Trace the long frame

Use the profiling tools to correlate input, main-thread work, rendering and scheduling.

Evidence Candidate cause
Long main-thread computation Parsing, sorting or expensive state work
Repeated layout/measurement Unnecessary invalidation or complex layout
Image work during scroll Decode or allocation on the critical path
Frequent garbage collection Excessive temporary allocation
Waiting rather than running Lock contention or scheduling pressure

Do not assume every late frame is GPU-bound.

Remove work from the interaction path

Precompute where appropriate, right-size images, avoid repeated allocations and keep state updates scoped. Test lifecycle cancellation so obsolete work does not continue competing with the visible screen.

A cache should have a clear owner and memory bound. An unbounded cache can trade jank for an eventual out-of-memory failure.

Measure repeated interactions

Run the same journey several times under comparable conditions. Inspect worst cases and distributions rather than only an average that hides visible stalls.

Preserve a regression scenario

Keep the scroll or animation test, representative data and trace. APKLint's Performance Checker can help structure the investigation, but it does not measure frame deadlines from static code or APK metadata. The evidence of improvement is fewer late frames in the same workload without a new memory or startup regression.

Locate the work that overlaps the missed deadline

Consider a list that stalls whenever a new image row enters view. Capture a trace covering that interaction and locate the late frame. If the main thread is decoding or sorting, investigate that work. If it is waiting on a lock held by another thread, moving more unrelated work to background threads may increase contention rather than help. A visual stall alone does not identify the processor or subsystem responsible.

The slow-rendering guidance describes diagnosing frame performance. Interpret deadlines in the device's actual refresh and rendering context. A frame interval of roughly 16.7 milliseconds follows from 60 Hz, while 120 Hz corresponds to roughly 8.3 milliseconds; those calculations are not universal guarantees of an application's available CPU budget.

Bound the cache while removing decode from scrolling

For the image-row example, request appropriately sized thumbnails and avoid creating redundant decoded copies. Give the cache a defined bound and cancel work for rows that no longer need it. Then rapidly reverse scrolling direction to check that an old image request cannot paint the wrong recycled row. Correctness of item identity matters alongside smoothness.

Compare the same populated list, scroll gesture, build type and device conditions before and after the change. Inspect frame distributions and the worst visible pauses, not only an average. Include a first visit and a cached return if users experience both, and record which case each result represents. Also include long text rows, since their measurement and wrapping can expose work absent from uniform short samples.

After reducing the demonstrated bottleneck, inspect memory and startup behavior for tradeoffs. Preloading every image could smooth one scroll while creating a large startup delay or allocation failure. Test configuration changes and cancellation so obsolete work does not keep competing with the current screen. Preserve the trace region and reproducible gesture in the regression record. An improvement is supported when the same interaction has fewer or smaller deadline misses without incorrect row content or uncontrolled memory growth. A package analyzer can suggest an investigation, but it cannot measure those frame outcomes from the archive alone.

Sources and further reading

  1. Android Developers: Slow rendering
  2. Android Developers: Profile your app performance

Reference review: 29 September 2026. Examples illustrate the workflow; check your installed versions, release artifact and account-specific Console requirements before applying them. This guide is not a claim that APKLint executed your project or verified your private account.

APKLint

Android inspection tools and practical release guides. About APKLint · Report a correction