大家好,我是展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
文章目录
- 引言
- 一、为什么帧率会抖动?
- 二、稳定帧率的核心指标
- 三、鸿蒙游戏最大的性能杀手
- 四、第一种优化:状态批量更新
- 五、第二种优化:Store拆分
- 六、第三种优化:避免频繁创建对象
- 七、第四种优化:UI组件拆分
- 八、第五种优化:减少无意义动画
- 九、System 优化比 UI 优化更重要
- 十、AISystem 分帧优化 Demo
- 十一、HUD优化 Demo
- 十二、终极方案:System + Store 分层
- 十三、一个关键认知升级
- 总结
引言
很多开发者第一次做鸿蒙游戏时,对性能优化的理解非常简单:
掉帧了 ↓ 看看CPU ↓ 优化代码或者:
动画卡顿 ↓ 减少组件然后问题似乎解决了一部分,但当项目变大以后:
角色越来越多 特效越来越多 状态越来越多 UI越来越复杂你会发现一个现象:
CPU并没有跑满,但帧率依然不稳定。
例如:
60fps 58fps 42fps 60fps 35fps玩家感受到的不是平均帧率,而是:
Frame Time(帧时间)波动,所以真正的优化目标不是:
跑得快。
而是:
跑得稳。
这篇文章我们从鸿蒙游戏架构角度聊聊:
如何实现稳定帧率,而不是虚假的高帧率。
一、为什么帧率会抖动?
很多人认为:
帧率低 = CPU性能差实际上大多数情况不是,真正的问题通常来自:
渲染抖动 状态抖动 布局抖动 对象创建 垃圾回收例如:
setInterval(()=>{store.hp--store.gold++store.exp++})看起来很简单,但实际上:
一次状态变化 ↓ 触发UI更新 ↓ 重新布局 ↓ 重新绘制如果频率过高:
FPS开始波动二、稳定帧率的核心指标
很多项目盯着:
FPS其实更应该看:
Frame Time例如,60FPS:
16.6ms意味着:
每一帧必须在16.6ms内完成如果某一帧:
30ms玩家就会感受到:
卡顿即使平均FPS还是60,所以:
稳定的16ms,比偶尔冲到120FPS更重要。
三、鸿蒙游戏最大的性能杀手
不是动画,而是:
状态更新风暴。
例如:
store.hp--store.mp--store.exp++store.gold++store.level++连续触发:
5次状态通知最终:
5次UI刷新四、第一种优化:状态批量更新
错误写法:
store.hp-=10store.exp+=20store.gold+=100每次都通知。
推荐:
store.update(()=>{store.hp-=10store.exp+=20store.gold+=100})思想:
一次通知 多次修改效果:
减少重绘 减少Diff五、第二种优化:Store拆分
很多项目:
GameStore里面:
玩家 敌人 任务 背包 技能全放一起,结果:
金币变化 整个UI刷新推荐:
PlayerStore SkillStore MissionStore InventoryStore例如:
PlayerHUD ↓ PlayerStoreSkillHUD ↓ SkillStore这样:
局部刷新性能提升非常明显。
六、第三种优化:避免频繁创建对象
很多人喜欢:
constenemy={x,y,hp}每帧创建,例如:
update(){this.enemy={x:100,y:200}}问题:
频繁GC导致:
Frame Spike也就是:
突然掉帧推荐:
enemy.x=100enemy.y=200直接复用。
七、第四种优化:UI组件拆分
很多人写:
GamePage里面:
地图 玩家 Boss 背包 任务 商城全在一个组件,结果:
任何变化 整个页面重新计算推荐:
PlayerHUD SkillHUD MiniMapHUD BossHUD独立组件,例如:
@Componentstruct BossHUD{}这样:
Boss变化 只刷新BossHUD八、第五种优化:减少无意义动画
很多项目喜欢:
缩放动画 透明度动画 位移动画同时执行,例如:
.animate({duration:300})几十个一起跑,结果:
GPU压力上升优化原则:
重要信息动画 保留 装饰动画 减少九、System 优化比 UI 优化更重要
很多开发者疯狂优化:
Text Image Button但忽略:
BattleSystem AISystem实际上:
逻辑层才是真正的大头,例如:
for(enemyofenemies){pathFinding()}100个敌人:
100次寻路直接卡死。
正确方案:
分帧执行例如:
frame%5==0才更新AI。
十、AISystem 分帧优化 Demo
错误:
updateEnemies(){enemies.forEach(enemy=>{enemy.updateAI()})}优化:
updateEnemies(frame:number){enemies.forEach((enemy,index)=>{if((frame+index)%5==0){enemy.updateAI()}})}效果:
AI负载均匀分散十一、HUD优化 Demo
错误:
Text(`${store.hp}`)每次变化刷新,优化:
@ObservedplayerStore局部绑定。
@Componentstruct HpBar{}单独组件,结果:
HP变化 只刷新血条十二、终极方案:System + Store 分层
真正的大型项目最终会变成:
Store ↓ System ↓ HUD ↓ UI其中:
Store 负责状态 System 负责计算 HUD 负责展示 UI 负责交互这样:
逻辑与渲染彻底解耦十三、一个关键认知升级
初学者关注:
FPS是多少进阶开发者关注:
Frame Time是否稳定高手关注:
为什么这一帧变慢因为:
真正影响体验的,从来不是平均帧率,而是最慢的那几帧。
总结
鸿蒙游戏渲染优化的核心思路:
减少状态通知 拆分Store 拆分HUD 控制对象创建 分帧执行System最终形成:
Input ↓ System ↓ Store ↓ HUD ↓ UI如果用一句话总结:
鸿蒙游戏优化的重点不是“让每一帧更快”,而是“让每一帧都稳定”。