
网罗开发小红书、快手、视频号同名大家好我是展菲目前在上市企业从事人工智能项目研发管理工作平时热衷于分享各种编程领域的软硬技能知识以及前沿技术包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。图书作者《ESP32-C3 物联网工程开发实战》图书作者《SwiftUI 入门进阶与实战》超级个体COC上海社区主理人特约讲师大学讲师谷歌亚马逊分享嘉宾科技博主华为HDE/HDG我的博客内容涵盖广泛主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告同时也会提供产品优缺点分析、横向对比并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。展菲您的前沿技术领航员 大家好我是展菲 全网搜索“展菲”即可纵览我在各大平台的知识足迹。每周定时推送干货满满的技术长文从新兴框架的剖析到运维实战的复盘助您技术进阶之路畅通无阻。文章目录引言一、为什么游戏加载会卡顿二、Profiling资源加载到底耗在哪三、ResourceSystem大型游戏的标准解法四、资源缓存架构设计五、对象池解决资源频繁创建问题六、预加载机制消灭首次卡顿七、大型鸿蒙游戏资源架构总结引言很多开发者第一次做鸿蒙游戏时都有类似经历项目刚开始的时候一个地图 几个角色 几个技能运行非常流畅、FPS 稳定、内存占用也不高但随着项目迭代地图越来越大 角色越来越多 特效越来越复杂问题开始集中出现进入场景卡顿 切换地图等待 Boss首次出现掉帧 内存持续上涨例如进入战斗 ↓ 黑屏2秒 ↓ Boss出现 ↓ FPS掉到30很多开发者第一反应是GPU不够或者ArkUI性能有问题但 Profiling 后往往会发现CPU占用正常 GPU占用正常 真正耗时的是 Resource Loading也就是资源加载 资源解码 资源上传 资源回收整个过程在大型游戏中资源系统往往比渲染系统更容易成为性能瓶颈。因为每一次场景切换、本质上都是一次资源重建。所以本文重点讨论ResourceSystem如何从架构层解决加载慢 掉帧 内存膨胀 资源泄漏等问题。一、为什么游戏加载会卡顿先看一个典型流程玩家点击开始游戏此时系统实际执行加载地图 加载角色 加载技能 加载配置 加载音频 加载特效例如Scene_A包含200张图片 80个动画 40个音频 100个配置文件很多项目会这样写asyncenterScene(){awaitloadMap()awaitloadHero()awaitloadSkill()awaitloadAudio()}看起来没有问题实际上所有资源同步加载导致IO阻塞 CPU解码 GPU上传全部发生在同一个时间窗口最终表现黑屏 卡顿 FPS下降二、Profiling资源加载到底耗在哪以一个实际项目为例进入 Boss 场景FPS 60 ↓ 28通过性能分析发现模块耗时图片读取32%图片解码25%GPU上传18%配置解析12%UI构建13%结果很明显75%以上时间 都浪费在资源处理而不是渲染这也是很多项目优化方向完全错掉的原因。三、ResourceSystem大型游戏的标准解法资源管理最忌讳哪里需要 哪里加载例如Image($r(app.media.hero))散落在几十个页面后果重复加载 重复解码 重复上传GPU最终导致内存暴涨因此必须引入ResourceSystem统一管理资源生命周期架构如下ResourceSystem │ ┌────────────────────┼────────────────────┐ ▼ ▼ ▼ Loader CacheManager RefCounter ▼ ▼ ▼ TextureResource AudioResource ConfigResource核心原则资源只能通过 ResourceSystem访问而不是UI直接读取四、资源缓存架构设计很多资源具有明显特点频繁使用例如主角头像 金币图标 按钮素材 常用技能图标如果每次重新加载读取磁盘 ↓ 解码 ↓ 上传GPU性能浪费巨大因此需要CacheManager设计。classCacheManager{privatecachenewMapstring,Resource()}读取流程请求资源 ↓ 缓存存在 ↓ 直接返回 ↓ 无需重新加载性能收益通常能达到50%以上五、对象池解决资源频繁创建问题大型项目经常出现子弹 技能特效 怪物实例不断创建销毁例如newBullet()每秒可能创建数百次最终GC频繁触发出现偶发掉帧解决方案Object PoolclassBulletPool{get()recycle()}复用对象避免频繁申请内存六、预加载机制消灭首次卡顿Boss第一次出现为什么卡因为图片未加载 特效未加载 音频未加载全部集中在同一帧解决方案awaitresourceSystem.preload([boss_texture,boss_skill,boss_music])进入场景前完成加载这样Boss出现 ≈ 直接显示用户几乎感知不到等待。七、大型鸿蒙游戏资源架构推荐采用Game Runtime │ ┌────────────────────┼────────────────────┐ ▼ ▼ ▼ Store System ResourceSystem │ ┌──────────────────────────────┐ ▼ Cache Manager ▼ Ref Counter ▼ Loader这里Store 负责状态System 负责逻辑ResourceSystem 负责资源生命周期形成完整 Runtime。总结很多开发者以为游戏加载慢是资源太大。实际上真正的问题往往是没有资源管理架构。当项目规模达到一定程度后直接加载 ↓ 缓存管理 ↓ 引用计数 ↓ 资源生命周期 ↓ ResourceSystem几乎是必经之路对于鸿蒙游戏开发而言如果说Store 是世界状态中心那么ResourceSystem 就是整个游戏运行时的资源调度中心。而一个优秀的 ResourceSystem往往比单纯优化几张图片更能决定游戏最终性能上限。