最全的Creator优化方案(二)

内存优化

1.场景策略选择-自动释放资源
1-1
勾选此项后,在场景切换的时候,会自动将旧场景中的使用资源自动释放掉。从而会减少内存占用。这里要注意其自动释放的并不包括场景中动态添加的对象。

2.管理动态加载的资源

  • 动态加载接口
cc.loader.load
cc.loader.loadRes
cc.loader.loadResArray
cc.loader.loadResDir

这些接口都是异步的,只有在加载完成后才能够使用。不然无法使用。

  • 自动释放资源
cc.loader.setAutoRelease
cc.loader.setAutoReleaseRecursively
  • 使用方法
cc.loader.setAutoRelease(预制体节点,true);

当场景切换时,由于资源已经释放,脚本中如果保留了引用,此时该引用将会变为非法引用。可以使用setAutoRelease和setAutoReleaseRecursively来保留这些资源。
setAutoReleaseRecursively指定资源及资源递归引用到的所有资源

  • 手动释放API
cc.loader.release
cc.loader.releaseRes
cc.loader.releaseAsset
cc.loader.releaseAll

但是如果直接使用cc.loader.release(预制体节点),释放一个预制体是不够的,因为资源是依赖一些图片资源的,此时只能去释放它所使用的配置文件。所以一般要搜索他所有的依赖资源然后释放才能完成正确的释放。
使用 cc.loader.release(cc.loader.getDependsRecursively(预制体节点) )方可完成。

使用Chrome中的Allocation Profile工具查看内存变化。

查找内存“垃圾”过程中需要注意的是:

注意简单的对象创建,例如数组,{}
注意不要忽略匿名函数
注意匿名函数使用的外部变量将被匿名函数持有
利用Timeline 观察 GC 调用频率
寻找长期不释放的蓝色内存

尽力使用可以重复使用的资源

  • 比如子弹,怪物等对象我们可以使用对象池进行创建管理
  • 尽量少使用cc.vec , cc.color , cc.size , {} ,[] 等这些类似的对象,尽量复用,减少来回创建的开销。

了解CPU的性能以及优化

使用Chrome中的Performance定位cpu使用情况
总之需要注意的是:
1、观察整体性能曲线图
2、观察分析局部显红热点帧
3、通过调用栈分析热点调用的函数
大多的情况下,都是由于自己没有合理的书写代码造成的,如内存泄漏,闭包处理,逻辑处理过于集中等情况导致的会出现热点帧的现象。此时我们可以利用一些插件来强制要求自己写好代码。如:ESLint,JSLint,TSLint工具。
JS代码级优化

很多时候我们对于CPU的优化都会从算法的方面着手,关于算法这一块优化方案多种多样,很多都需要根据项目的实际情况以及游戏的设计出发的。
我们经常会聚焦于算法级的优化上,而忽略掉代码级的优化。
这里带来的就是代码级的优化

1、数组操作
增加数组元素时,更推荐使用:

array[array.length] = 0;

相比较push的方法,代码执行效率上我们可以看下对比:
在这里插入图片描述
会有一定的提升,但提升的空间有限,因此不是强烈推荐,只是针对需要反复大量执行的代码时,更推荐使用。比如大量的a星寻路计算时,可以在编码时随手注意一下

2、for循环
常用的for循环我们有几种方式

for(let i = 0;i < arr.length; i++)
for (const key in arr)
for (const key of arr)
arr.forEach(element => {})

除了for-in这种方式外,其他三种for循环方式没有什么太大的差距
在这里插入图片描述
强烈不推荐使用for-in的方式进行for循环,效率极其低下,同时随着游戏不断的运行,for-in还不能被jit优化。因此千万不要使用for-in

3、arguments
js中如果要实现类似C++中的多态,可以通过arguments去达到。
这样我们可以通过相同的接口,只是参数的不一致从而达到不同的逻辑运行效果

function argumentsTest () {
    if (arguments.length === 1) {
        //......
    }
    else if (arguments.length === 2) {
         //......
    }
}

类似上面这样的使用。
这种方式虽然使用上看起来很秀,但要注意的是,性能也是极其低下的,需要这种情况,不要偷懒,多写几行代码,拆分成几个不同的函数进行调用会更好。
强烈推荐不要在工程中使用arguments

4、try-catch or try-finally 以及 eval
强烈建议不要使用任何的try-catch or try-finally 以及 eval,执行效率极其低下,很容易造成游戏的卡顿。
例如try-catch or try-finally系列,如果没有错误抛出,那就还好。一旦有错误抛出,效率直线下降。

5、global value
在使用全局变量时,类似下面这样

gIndex = 0;
for (let i = 0; i < n; i++) {
    gIndex += i;
}

执行结果:在这里插入图片描述
不要直接使用gIndex,使用局部变量进行一下转换,效率会快很多:

var localIndex = gIndex; 
localIndex = 0;
for (let i = 0; i < n; i++) {
    localIndex += i;
}

执行结果:在这里插入图片描述

以上就是一些代码级优化上需要注意的地方,可以看到,如果时一些热点函数,需要大量重复执行的话,如果使用这些优化方案,通常会带来很大的提升。这也是从另一个角度去进行CPU性能的优化
最后感谢@BigBear023 的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章