最全的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 的博客

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