- System draw app's screen after every 1000/60FPS =
16.7ms. If our app CANNOT complete logic in16.7msit will force system to drop frame which called a jank. - To avoid it we can: use Layout Inspector, profile GPU rendering, use
ConstrainLayoutto reduce nested layout, moveonMeasure,onLayoutto 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
LinearLayoutthat uselayout_weightor nestedRelativeLayout. - Reuse layout using
<include>or<merge>. Use dynamic views with views rarely use. UseRecyclerViewinstead of the oldListView. - Apply
ViewHolderdesign 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
linttool to check layouts.