Global IM UIKit 性能与最佳实践
Global UIKit 的性能关键在状态机与列表:避免整表刷新、控制高频事件、分页加载与复用 Cell。以下建议以契约 behaviors 为依据,给出可执行的实现口径。
契约中的性能相关行为
| 组件 | 契约行为 |
|---|---|
ChatViewController | 消息按 seq 渲染、去重、发送中/失败/已读状态 |
ChatViewController | 上拉加载历史(beforeSeq 分页) |
ChatViewController | typing 指示与节流 |
ChatViewController | 键盘避让与滚动定位 |
ChatListViewModel | load/refresh/loadMore 幂等 |
ChatListViewModel | 合并 CONVERSATION 事件增量 |
ChatViewModel | markRead 去重与节流 |
ChatViewModel | 合并 MESSAGES/READ_RECEIPT/MESSAGE_RECALLED 事件 |
ChatDataSource | 按 seq 升序/分页状态 |
ChatInputController | 草稿自动保存(防抖 500ms) |
ChatInputController | typing 节流(2s) |
实现建议
| 场景 | 建议 |
|---|---|
| 会话列表刷新 | 按会话 id 做 diff,只刷新变化行;不要每次事件整表 reload |
| 消息增量 | 合并 MESSAGES 事件批量插入;按 seq 去重;滚动位置只在底部时自动跟随 |
| 历史分页 | `loadMore` 幂等,加载中不重复触发;`beforeSeq` 游标由 ViewModel 维护 |
| 高频 typing | 输入区节流(契约 2s);收到 typing 只更新状态条,不刷新列表 |
| 已读上报 | 合并可见消息批量上报;同一批不重复发送 |
| 草稿保存 | 防抖 500ms 写本地,退出页面时立即 flush |
| 主题切换 | 只更新令牌与受影响视图,不重建 ViewController |
| 大图 / 文件 | 异步加载 + 占位图;Cell 复用时取消未完成请求 |
测量方法
Shell
# Instruments:Time Profiler / Allocations / Core Animation
# 1) 冷启动到会话列表首屏
# 2) 1000 会话滚动帧率(目标 ≥55 FPS)
# 3) 10 万消息进入会话 + 上拉分页
# 4) 连续收发 1 小时:内存无持续增长
# 5) 断网 30s 恢复:状态机回到 loaded 且不重复渲染验收清单
- 列表滚动无明显掉帧;Cell 高度计算不阻塞主线程。
- 收到 100 条离线消息后,UI 合并刷新而不是 100 次 reload。
- 快速进出会话页无内存增长(订阅已取消)。
- 主题 / Dynamic Type 切换后布局正确,无重新登录或重建客户端。