背景
游戏内嵌社区是玩家在游戏内社交的重要平台,现有的社区SDK在PUBG经过三年迭代已具备成熟社交功能,但在拓展新业务时面临着多业务界面和功能差异大、通用性不足的问题,为了能灵活满足不同游戏诉求,需要打造一个功能可插拔、复用性高、可快速扩展新业务的内嵌社区SDK。
选型
综合考虑了性能、交互体验、改造成本和后续扩展性,最终选择基于SDK1.0升级SDK2.0作为LOL内嵌社区。
方案设计
1. 模块化灵活组合
SDK1.0所有功能都在一个模块与业务强耦合,不利于新业务定制。因此2.0结合产品能力和底层实现,对项目代码进行分层和模块化:
- 主入口:顶层管理、模块服务注册和初始化
- 业务模块:划分遵循单一职责原则,统一通过模块服务管理和通信,面向接口开发,有独立资源,可独立运行,可灵活组合打包,是实现多业务定制化的重点
- 通用模块、第三方库:公共必需的模块,向上提供基础服务
其中,实现业务模块灵活组合的两个关键点:
-
模块管理标准化(红线)
- 以ServiceMgr为核心统一管理业务模块,包括接口列表和注册、获取模块方法
- 每个业务模块实现各自对外接口,并在初始化时注册到ServiceMgr
- 模块间调用通过ServiceMgr间接获取,而不是直接依赖
-
模块配置自动化(蓝线)
- 构建流水线时,支持配置打包模块,会在顶层入口.yaml配置文件动态导入依赖模块并在ServiceMgr动态注入注册代码
- 无需修改代码,一键满足业务不同打包需求(如全球包、日韩包),支持并发打包出包,整体提高研发效率
2. 差异化精细适配
完成模块化只解决了定制模块解耦,对于公共模块差异还要做精细适配:
-
上下游适配
- 通信协议复用,表维护后台服务及资源配置,动态生成当前配置,实现快速切换环境
- 账号体系完善,国内需区分登录平台和系统
-
视觉还原:除首页框架调整,其他页面交互基本一致,但视觉风格不同,需逐个还原以下资源:
- 本地资源 :维护不同业务资源包,动态生成当前资源,实现快速替换同名同格式资源
- 本地词条 :保留海外多语言方式,修改默认语言,本地内置默认词条并支持远端下发,实现快速修改默认词条
- 本地字体 :定义字体接口,实现快速满足不同业务对字体、粗细和行间距的要求
- 颜色:命名颜色值,抽象主题色,统一映射表维护,实现快速修改全局颜色
-
全局换肤
- 预设配置项在管理端运营,避免通过换图热更增加后期开发成本
- 使用换肤管理器、换图组件和换色组件降低接入成本
✧ Widget框架解耦
以上流程基本实现业务层代码共享、业务独立、资源分离的目标,但开发中发现以下问题:
- Flutter的Widget嵌套式语法导致UI构建和事件处理耦合在同一个Widget中,增删代码需考虑多业务和横竖屏影响,复杂度变高、维护性变差
- 多数Widget仅UI细节差异,导致引入大量与UI相关的if-else,理解成本变高、可读性变差
因此,将Widget中的UI和逻辑解耦,实现不同业务子类对UI或逻辑的独立维护,职责清晰,避免相互影响。其中三个关键元素:
- Cell:组件的最小单位,由View和ViewModel构成
- View:负责布局界面,从ViewModel获取展示数据和事件
- ViewModel:负责业务逻辑,数据变化时通知依赖View刷新数据
3. 体验和性能优化
✧ 内存优化
-
大图压缩优化
- 问题 :用户上传的各种头像通常以小图呈现,直接加载原图会导致内存占用高和流量浪费,而简单压缩无法解决不同场景显示尺寸不一发生频繁加载的问题
- 解决方案 :实际裁剪尺寸采用分组策略,尺寸定义上符合设计习惯,最大程度复用缓存图像,减少内存占用和流量消耗,且保证图像质量
-
性能提升 :首页内存峰值降低30MB,平均节约45%流量
✧ 帧率优化
-
动图渲染优化
- 问题 :首页滚动卡顿明显,经PerfDog测试比半年前版本掉了4帧
- 解决方案 : 使用Flutter DevTools监测性能发现UI线程Paint耗时明显增加,借助Highlight repaints定位是Lottie和Gif影响整个页面发生频繁重绘。办法是使用RepaintBoundary组件包裹动图,利用Flutter图层合成机制,将动图绘制结果缓存到单独图层,发生变化只自重绘而不影响页面其他图层
-
视频启播优化
- 问题 :测试首页快滚FPS时发现,滚动中发生视频加载
- 解决方案 :快滚时手指反复按下抬起(发现每次按下的ScrollStart会先调用前一次的ScrollEnd)导致多次回调ScrollEnd误触视频加载,而Flutter无法准确描述快滚停止事件。办法是ScrollEnd后延时加载,确保页面稳定,且避免和曝光检测任务同时竞争资源,经线上实验测试延时最少30ms对提高FPS有效且不影响启播体验
- 性能提升 :经PerfDog测试首页快滚30s FPS提升5帧
✧ Flutter组件优化
-
多平台滚动体验优化
- 问题 : Flutter原生滚动实现有差异,导致iOS视频起播较慢
- 解决方案 :结合iOS减速运动曲线、模拟摩擦停止效果,扩展Flutter滚动物理属性,增加速度衰减率以加快减速、提高速度停止阈值以加快停止,实现更快启播
-
多语言字符显示优化
- 部分泰语提前换行或打点 。经查由泰语中显示在基础字符上的声调字符(Combining Character)造成,有几个超出显示,若在文本末尾则导致实际宽度溢出。办法是扩展Flutter Text组件,针对性追加空格补齐宽度
- 部分阿拉伯字符显示乱码 。经查是阿语某种组合字符(Hamza),在Flutter文本引擎LibTxt处理多语言字形时,针对阿语进行了字符连接的调整,和非阿语字符组合则无法正常渲染。方法是插入零宽度空格\u200B,确保能和空白正确组合显示
- 部分泰语提前换行或打点 。经查由泰语中显示在基础字符上的声调字符(Combining Character)造成,有几个超出显示,若在文本末尾则导致实际宽度溢出。办法是扩展Flutter Text组件,针对性追加空格补齐宽度
总结与展望
通过LOL社区适配,完成对社区SDK的通用化改造,和对基础体验的整体升级。尽管在后续迭代中,考虑到国内和国外应用在底层逻辑存在较大差异,进行了分支管理独立运行的技术调整,但仍然保留通用化做法,以便未来作为国内和国外社区的模版继续扩展。
相关简书文章:
Flutter|解耦初实践
Flutter|页面换肤实践
Flutter流畅度优化之过度绘制
Flutter滑动停止事件ScrollEndNotification
Flutter|滑动体系之ScrollPyhsics
Flutter Text组件和国际化-阿语
Flutter Text组件和国际化-泰语