0%

加载大量View的优化策略

在项目的实际运行中,发现有用户创建了大量视图,多达4000多,在进入项目的时候一次性创建不仅会消耗大量内存,还会卡顿,所以需要对这部分进行优化。

优化的方向分为

1、加载策略优化

项目中的 View 并不是同时全部可见的,有很多初始状态是隐藏,所以在加载的时候遇到是隐藏状态的,全部加入延时队列

即使如此,第一批需要初始化的 View 依然很多,由于与 Layer 相关的操作只能在主线程进行,所以尽量把需要计算的操作提前计算缓存。

然后分批次初始化 View ,虽然有一定耗时,但是配合加载动画可以有效避免卡死带来的影响。

2、绘制层优化

由于大部分的控件都是不会被添加点击事件的,也不存在动态添加时间,所以初始化的时候没有事件的都使用 Layer 进行显示,可以极大的缩减内存占用与初始化速度

3、控件的存储

在项目中控件之间有很多层,事件的交互通过对应的 ID 来存储,所以直接使用 Dictionary,它本质是一个散列表,所以存取操作的时间复杂度基本处于 O(1) 级别,内部的桶内只存储控件的指针,一个只有8字节,所以不会占用多少内存。

4、控件的复用

在一个项目详情页,会有多个场景与页,控件只属于某一个场景下的某一页,这样在进行切页操作的时候,如果将之前的控件全部释放,再创建新的,那么会造成很大的性能浪费,所以在首页加载完毕后,所有控件都进行缓存,切页后,控件全部从屏幕移除,从缓存中取对应类型的控件进行新的model赋值操作,进行复用,这样可以节省下释放内存与分配内存所消耗的内存,缺点是会造成一定的内存浪费,但是运行效率优化,基本都是空间换时间。

5、透明度 图片 圆角

因为项目底下是 Unity 的 3D 页面,所以上面的试图除了用户主动设置不透明色,否则都是透明、半透明的,所以这透明上没法像普通列表页这种做优化。

图片都是网络图片,下载到分辨率超出 4K 的图片,进行压缩,如果图片控件设有圆角,直接将图片进行裁剪,这部分操作都处于子线程,最终将处理完解码后的图片在主线程进行绘制。

后续的优化

虽然现在已经不会把 UI 卡死,但是首次进入项目大批量的创建控件,还是会消耗 1 - 4 秒的时间,内存占用也比较高,所以接下来准备将大量没有动画的 layer 进行合并,最终可能会 十几个、几十上百个 Layer 合并成一个大的 Layer。