Skip to content

页面卡顿优化

页面卡顿的原因及解决方案:

AppBarLayout

通常情况下使用 AppBarLayout 需要监听滑动状态,然后修改部分 View 的显示状态,但可能存在某些异常。

问题及建议

问题:回调方法内状态检查代码较为复杂

不一定调用本类方法也可能是调用其它类的方法。

措施:建议将状态进行内存缓存,并在合适的方式进行更新内存缓存状态。

问题及建议

问题:多个相关 View 需要控制显示/隐藏,使用遍历进行设置;

措施:尽量避免使用列表遍历的方式,是否可以为多个 View 设置统一的 ViewGroup 或 使用 ConstraintLayout#Group 进行控制。

问题及建议

问题:多次调用同样的方法,尤其是更新 View 显示状态

措施:考虑新增状态进行区分设置 View 显示状态,尽量避免多次使用。

mFfFansView.visibility = View.GONE
mFfFocusView.visibility = View.GONE
// changeTeacherView(View.GONE) 被优化
if (mIsLongBg) {
    changeTeacherView(View.GONE)
} else {
    mIvHeadAvatar.visibility = View.GONE
}

viewTreeObserver

GlobalLayoutListener

一般设置此回调只在获取当前 View 的位置信息,如 measureHeight、measureWidth。

问题及建议

问题:调用 addOnGlobalLayoutListener 之后没有及时 remove

措施:调用 add 方法时不传入匿名的 OnGlobalLayoutListener 实例对象,且在合适的位置调用 remove 方法。

建议:获取到所需的 measureHeight、measureWidth 等尺寸信息后就 remove,不然可能导致每次 Layout 变动均会被触发。

建议

使用检查是否真正需要使用其进行捕捉尺寸信息,如果非必须建议改用其他方式。

  1. 使用 TouchDelegate 设置点击区域的放大;

ConstraintLayout 性能

使用传统布局「RelativeLayout」构建 Item 并循环添加 10+ 次 View 进父布局

使用谷歌推荐「ConstraintLayout」构建 Item 并循环添加 10+ 次 View 进父布局

图中可以看到 MineGridItemView 的 init 方法耗时差异特别明显:

RelativeLayout:561091、560998,平均值: 561044.5 ConstraintLayout:624168、624079,平均值:624123.5,比 RelativeLayout 高了 63079 微秒

Inflate 性能

中的图片可以看到 Inflate 的性能也不是很好,而且多次调用同样存在性能问题,如果布局较为简单,可以尝试改用手动操作 Java 对象的方式创建。如果可以的话,可以使用 Google 官方推荐的 jetpack Compose