- System draw app's screen after every 1000/60FPS =
16.7ms
. If our app CANNOT complete logic in16.7ms
it will force system to drop frame which called a jank. - To avoid it we can: use Layout Inspector, profile GPU rendering, use
ConstrainLayout
to reduce nested layout, moveonMeasure
,onLayout
to background thread, usematch_parent
. - Long-running task should run asynchronous outside UI thread.
- Avoid nested
RecyclerView
, avoid callnotifyDatasetChanged()
in RV adapter with small update. Apply DiffUtil.Callback to calculate the diff between two lists to minimal number of updates. - Use RV Prefetch to reduce the cost of inflation in most case by doing the work ahead of time, while UI thread is idle.
- RV
onBindViewHolder()
or ListViewonBind()
called on UI thread -> it should be very simple, and take much less than one millisecond for all but the most complex items, it should only get data from POJO and update ui.
- Optimize layout hierachy to avoid nested
LinearLayout
that uselayout_weight
or nestedRelativeLayout
. - Reuse layout using
<include>
or<merge>
. Use dynamic views with views rarely use. UseRecyclerView
instead of the oldListView
. - Apply
ViewHolder
design pattern for lists to reuse row item view instead of create new View object. This will avoidfindViewById()
overhead. (Number of row item views = number of rows inside screen + 2 (threshold) -> recycle row item views to reuse when scroll). - Use
lint
tool to check layouts.