分包资源加载太慢 垃圾3.x

虽然知道可能没有人会理会 但是我还是想发个帖子来描述一下我使用3.x一年半以来遇到的一个个糟心的问题的其中一个 先说明 无法提供dmeo 我试着写了个demo无法复现问题 下面直接说问题吧

用3.x结合微信的云开发做微信小游戏 由于包体太大 整包超过了20M所以 做了分包 把分包 放在的微信的云存储 然后 游戏中下载该分包 一切都很顺利 可以从云存储 顺利拿到分包 并获取分包下面的所有资源 但是神奇的一幕还是 出现了 用该分包 动态加载该分包下面的资源第一次的耗时是3秒多 后面再加载这一份同样资源是1.2秒左右 引擎版本3.2 有这个问题升级到3.4.0还有 虽然没有每个引擎版本都试一下 但是我非常肯定 无论哪个版本都有这个问题 别问为什么 因为我用3.x开发用了一年半了 3.0 3.1 3.2 3.4.0 都有使用过 如果任何一个人能够使用过这几个版本 并开发一年半左右 都能自然体会使用过后其中的奥妙

下面会有具体的代码和分包加载资源的时间截图


map_bundle 就是从云存储下载下来的已经实现的分包机制的分包 本包

然后
map_bundle.load(res_path, Font, function (err, res) { 这是在干嘛 我觉得该懂的都懂 就不解释了

最有意思的是箭头指向的各个时间才是重头戏

接下来就是见证奇迹的时刻

我不记得从看到的啦 说引擎的加载过的资源都会被缓存起来 后面再次加载这个资源就会快了 很明显这句话在我这里不适用

先说一句吧 这个我问题我也自己实现了 解决方案 只是解决方案并不完美 今天发这个帖子 纯粹是来吐槽 3.x现在的垃圾和我的不满情绪的(出了一万个新功能 迭代了一亿个版本 没有一个稳定的3.x版本 就好像汉武帝穷兵黩武打天下 国家版图是扩大了 可是 老百姓 都快饿死了 视而不见 )


12毫秒 8毫秒 6 毫秒 6毫秒 7毫秒 !!!
好快啊 没问题啦!!!

开个玩笑 真要这么快, 我就改歌颂啦。

上面的时间是pc模拟器的时间 微信开发者工具的打印时间

手机才是重头戏 尤其是安卓机 一加8T 不算老吧 性能也还行我个人觉得



吐槽完毕 不满情绪发泄了

2赞

确实,之前同一张散图每次都是从bundle加载显示,每次都是肉眼可见的慢,后来改成将加载的存起来 下次直接使用就很丝滑了。

1赞

各种问题生气 吐槽吐槽

对 我也是这么解决的


用公司项目测试了一下,发现是真的有这个问题,还好我自己之前写的是有单独的map缓存,但公司的没有 :rofl:
3.3.2

抱歉,加载过的资源实际上也是从缓存里面读取的,只是读取之后,会利用 setTimeout(() => {}, 0) 下一帧返回,但微信上的 setTimeout 有 bug, 会等待非常长的时间,之后版本我们将不再使用 setTimeout, 改为在主循环中回调

1赞

我这个是原生安卓

主要是就算本地有缓存,加载机制也会通过事件机制下一帧才返回,所以会有一帧的延迟 解决的话,可以自己封装下 加个缓存查询 大概是这样的

                let info = bundle.getInfoWithPath(assetName, type)
                if (info) {
                    let uuid = info.uuid //cc.assetManager.assets里面存储的key
                    if (uuid) {
                        let cachedAsset = cc.assetManager.assets.get(uuid)
                        if (cachedAsset && cc.isValid(cachedAsset)) {
                            callback && callback(null, cachedAsset)
                            return
                        }
                    }
                }

                bundle.load(assetName, type, (err, asset: cc.Asset) => {
                        callback && callback(err, asset)
                });
4赞

这个可以,我之后也是准备这样做把map替换掉

已经有接口了啊,bundle.get 方法就是

3赞

厉害了,很久没看源码了,原来已经进化了 :call_me_hand: :call_me_hand: :call_me_hand:

请问是怎么存呢,用creator的cache吗,还是自己写个map? 非常感谢~

不用释放吗?万一很多内存不够怎么办

你这是自己写的有问题吧,不怪官方,正确方法你应该先加载 bundle.load 获取应该使用 bundle.get

我感觉这种做法是 明显的把锅甩到用户上的问题,load 后 get 的时间比再次 load 短,那么我们是不是自己又要封装一次 load?那么为什么不直接在引擎的 load 里面先调用 get 呢?

@jare

对呀!为什么呢?

三月底之前攒的调休就要被清空了,所以最近请假的人非常多,找不到人问了。等过完年我会跟进这个问题。

2赞

标记下,看看有没有解决

引擎的 load 里面是的调用了 get,get 为什么比 load 短的原因,是因为 load 是异步接口,即使在 load 内部使用了 get 查询到了值,是不能直接返回的,也是需要等到下一帧回调,否则可能会出现一些没法预估的表现。这是为啥比直接调用 get 长的原因。

引擎会确保所有回调一定是异步而不是同步的,否则会导致回调的执行时机不可预测,引起逻辑的不确定性,游戏就会出现奇怪的问题。这里的延迟只会有一帧,不会造成太大的影响。