优化 Prefab 创建速度的小技巧(仅支持 1.7)

在之前很多帖子中,我有谈到过目前 Prefab 加载速度慢的原因。Prefab 第一次实例化时,会自动进行一次预优化。预优化需要不少时间,但是预优化后,后续再次实例化同一个 prefab,速度就会飞快,比手动创建节点还快。

但是有不少人将 Prefab 作为多人协作或者分步加载的工具,这些 Prefab 实际上只会实例化一次,这样一来预优化反而会大大降低 UI 的创建速度。

既然知道原因,如何优化就很明确了。只需要在 Prefab 上加一个选项,让用户选择是否启用预优化即可。可惜我最近琐事太多,这个功能虽然被排到了 1.8,但 1.8 最快也要春节前。因此在这里先介绍一个方法,让大家自己先手动禁用预优化。

这个方法只支持 1.7,具体做法是:在实例化 Prefab 之前,手动设置 cc.supportJit = false;,在实例化之后,需要把这个标记重置为 true。

就像这样:

if (cc.supportJit) {
    cc.supportJit = false;
    var ui = cc.instantiate(prefab);
    cc.supportJit = true;
}
else {
    // 如果是特殊的不支持 JIT 的平台,则不需要优化,也不能强制设置 cc.supportJit 为 true
    var ui = cc.instantiate(prefab);
}

欢迎大家反馈一下这样优化的效果如何。


更新:1.10.0 会直接整合该优化,如果你已经使用了上面的代码进行优化,1.10.0 不会报错,但需要重新在 UI 上选择一遍,否则优化会失效。

10赞

插眼 插眼插眼

插眼 插眼插眼

1024

1024

插眼插眼插眼

loadScene之前设置的话会让场景加载快一些吗?:sweat_smile:

不会 1234

我1.7beta 版,vscode 没有出现提示数据

感觉这个预加载的优化比较尴尬, 毕竟如果需要重复创建的话, 应该会用对象池吧~.~

首次加载速度有明显提升,后续加载速度会稍慢一些

2赞

但是有不少人将 Prefab 作为多人协作或者分步加载的工具,这些 Prefab 实际上只会实例化一次
这句话是什么意思,什么情况会出现这样的问题

对象池和实例化不同。对象池是为了解决对象复用。实例化是为了解决新对象创建。实例化速度上去后,初始化对象池性能也会提升。

就是说如果将 Prefab 用于动态加载界面的话,整个界面加载进来只会创建一份。

谢谢,请问你测试用的是什么平台?

插眼插眼

1234

在执行动画的时候调用cc.instantiate去实例化,会明显卡顿,应该是实例化导致的,这种场景需求。
还有一个疑问,去实例化一个较大的prefab,这个prefab c包含a,b两个prefab的事例,另外一种情况就是分别代码实例化a,b在添加到c上,这两种情况。个人理解应该是第一种会更快,因为实例化prefab的时候会有重复的工作在里面。不知道是不是这样

我用iphone 7p测试了一下我们最复杂的一个prefab

未用此方案时:
load prefab: 78 ms
cc.instantiate: 41 ms
界面初始化到打开: 955ms

使用此方案:
load prefab: 73 ms
cc.instantiate: 16 ms (性能是提升了1倍)
界面初始化到打开: 923 ms

但由于界面复杂,用在其它的时间占了绝对,这个优化虽然表面提升了一倍,但实际也是没啥帮助。。。