bit-assets:资源加载管理,一个批次名搞定进出场景的资源释放

它解决什么问题

战斗场景要加载一堆资源:角色模型、特效、音效、UI 预制体。进场景的时候一个个 resources.load 手写没问题,但退出场景的时候呢?这些资源到底该不该释放、有没有漏释放导致内存越涨越高、有没有释放了还在用的资源导致报错——这些问题手动管理起来非常容易出错,尤其是资源来源分散在好几个模块里加载的时候,谁也说不清楚”这个资源到底还有没有人在用”。

bit-assets 用批次的概念解决这个问题:加载的时候给一批资源打上批次名,退出场景时一句话把整批全部释放,不用一个个记。

安装

npm install @gongxh/bit-assets

核心用法

批量加载一批资源

import { AssetLoader } from '@gongxh/bit-assets';

const loader = new AssetLoader('battle'); // "battle" 就是批次名
loader.parallel = 10; // 最大并行加载数
loader.retry = 2;     // 失败自动重试 2 次

loader.setCallbacks({
    onProgress: (finished, total) => console.log(`加载中 ${finished}/${total}`),
    onComplete: () => console.log('全部加载完成'),
    onFail: (failedList) => console.log('部分资源加载失败', failedList),
});

loader.start([
    { path: 'battle/prefabs/monster', type: Prefab },
    { path: 'battle/audio/bgm', type: AudioClip, bundle: 'battle_res' },
]);

某个资源加载失败了不用整批重来,调 retryDownLoadFailedAssets() 只重试失败的那部分:

loader.retryDownLoadFailedAssets();

取资源、释放资源

加载完的资源存在全局资源池里,随取随用:

import { AssetPool } from '@gongxh/bit-assets';

const prefab = AssetPool.get<Prefab>('battle/prefabs/monster');

// 通过 UUID 拿也可以
const asset = AssetPool.getByUUID<SpriteFrame>(uuid);

退场景,一键释放整批

AssetPool.releaseBatchAssets('battle');

这就是整个模块设计的核心——加载的时候按批次分组,释放的时候按批次一起清,中间用了哪些资源、加载了多少次都不用手动对账。

加载多次等于加载一次

同一个资源路径被多个地方分别请求加载,bit-assets 内部会识别出这是重复请求,只真正加载一次,后续请求等这次加载完成后直接拿引用,不会因为多个模块都要用同一张图就触发多次网络/IO 加载。这个特性省掉了很多”到底谁负责加载这个资源”的模块间协调工作——大家各自声明需要什么资源就行,谁先谁后都无所谓。

避坑提醒

  • 批次名要在项目里统一规划好(比如按场景名命名),批次名重复使用会导致本该独立管理的两批资源被当成一批一起释放,容易误删还在用的资源。
  • releasePath/releaseDir/releaseUUID 这些单个释放的方法和批次释放可以混用,但混用之后批次里剩下的资源数量对不上直觉,尽量保持”批量加载就批量释放”的一致性,别中途手动摘掉批次里的某个资源。
  • parallel 设太大在弱网环境下不一定更快,反而容易多个请求互相抢带宽导致全部变慢,按目标平台网络状况适当调整。

项目信息

零依赖,独立使用,跟 bit-ui 的窗口资源加载是两套独立的机制,各自管各自的。