記一次cocos-js/cocosCreator全面優化記錄(原創)


 

如果文章有誤解的地方,歡迎指出,將在第一時間改正,有更好的實現方式希望留下你的評論!

 

優化內容:游戲包體積,CPU、GPU方面優化,內存優化,其他優化

 

注意事項:

 

有句老話,If you can't measure it, you can't improve It

任何形式的問題都有它不同的解決方案,問題在於能否直擊在問題的中心點上。

 

要優化一個系統的性能(例如Web請求響應時間),你必須首先准確地測量各方面的數據以分析最終的症結。

------比如當前系統的性能究竟差在哪:是請求解析不夠快?還是查詢 DB 太慢?。。。

------比如游戲加載太慢是慢在哪里:流程問題?還是資源量太大下載或解析太慢?還是是服務器通訊不夠快?。。。

 


具體該如何去量化分析性能?這里列出了一些工具參考:

  1.chrome的開發工具

  2.Xcode中的Instruments動態分析工具

  3.微信開發者工具

  4.使用SpectorJS插件分析當前渲染每個DrawCall的具體信息

 

 

優化原則:

  1.效率、成本。不要花百分之九十的時間、成本去嘗試獲取百分之一的性能提升。

  2.不提前優化、也不過度優化(有些內存的優化是建立在消耗更多的CPU換取的,這類行為要注意適量原則,主要取決於收集到的數據,以建立平衡,獲取最優效果)。


 

 

優化前言

 

一提到游戲優化,很多人都會立刻想到在cpu和內存上下功夫。但卻忽略了最重要的可維護性。。。。。。。(跑題了?沒有的事)

 

因為 編碼規范很重要編碼規范很重要編碼規范很重要

 

既然是講優化為何又扯到代碼規范?唔,這個話題可能有爭議。不過今天不針對這個話題討論。

 

 

不過我這里想引用以下2個著名的效應來應證我要提倡編碼規范的理論,效應自己意會這里不做討論。

 

破窗效應
狄德羅效應


推薦書籍:《
代碼整潔之道》:代碼質量與其整潔度成正比。干凈的代碼,既在質量上較為可靠,也為后期維護、升級奠定了良好基礎。

規范建議: 養成不斷的批判對待自己代碼的習慣,尋找重新組織、改善結構和正交性機會。

 

 

 

 

 

 


 

優化:

 

一、游戲包體積優化

 

1.根據自己的需求選擇引擎模塊,剔除引擎中不需要的模塊。

 

2.資源優化

  聲音文件:壓縮聲音數據,多聲道變單聲道,降低采樣率。

 

  圖片:

    1.避免大尺寸的圖片出現,純色圖片或有規律的圖片用一像素的圖片表示。

    2.帶圓角的按鈕背景圖片用九宮格形式展示。

    3.復用一切可復用的資源。

    4.紋理按功能需求合並,並壓縮。

      5.動畫優化: 如果動畫內存過多,比如幀動畫,可以考慮使用骨骼動畫來代替幀動畫。

 

  plist:可以考慮按需求合並

 

  其他:能壓縮、就壓縮

 

注意以下合理性:

1.不能無腦的划分資源模塊,需要考慮DrawCall問題,避免渲染穿插造成cpu過多消耗。

2.如果label內容是字母、常用符號、數字,可以使用位圖bmf,並按需求合並到ui中,避免因為label的穿插渲染導致合並渲染被打斷。

 


 

二、CPU、GPU方面優化

 

1、概念:

  CPU (中央處理器) : 通過指令來調度,管理和協調各種不同的任務,處理復雜的邏輯,使用的是串行編程模式。

 

  GPU (圖形處理器) : GPU接受CPU的調度,可以處理大量重復的數據集運算和頻繁的內存訪問,使用的是並行編程模式。

 

  DrawCall : 中文譯為“繪制調用”或“繪圖指令”。是一種行為(指令),即 CPU 調用圖形 API,命令 GPU 進行圖形繪制。

 

2、3者流程關系:

 

 

 

 

上圖只是對渲染管線的部分概括,方便大家理解,實際的圖形渲染管線比較復雜,不在本文討論范圍內。

  

從上圖中可以看到在渲染管線中可以看到以下2個流程

1.每一次 DrawCall 前,CPU 都需要做一系列准備工作,才能讓 GPU 正確渲染出圖像

2.CPU 的每一次內存顯存讀寫、數據處理和渲染狀態切換都會帶來一定的性能和時間消耗

 

理解了3這的工作原理和關系后,我們來看一下流程瓶頸:一般來說 GPU 渲染圖像的速度其實是非常快的,繪制 100 個三角形和繪制 1000 個三角形所消耗的時間沒差多少。但是 CPU 的內存顯存讀寫、數據處理和渲染狀態切換相對於 GPU 渲染來說是非常非常慢。所以實際的瓶頸在於 CPU 這邊,大量的 DrawCall 會讓 CPU 忙得焦頭爛額暈頭轉向不可開交,而 GPU 大部分時間都在摸魚,是導致游戲性能下降的主要原因

 

渲染優化:

  1、資源划分:按功能或者按需求合並圖集,盡量促成合並渲染。

  2、按需求合並部分文件,減少io。

  3、嚴格控制渲染節點樹。相鄰渲染節點盡量來自同一個圖集,特別是再循環中創建的節點樹。

  4、限制底層繪制分辨率。

  5、控制游戲幀率。

  6、優化算法、降低邏輯復雜度,提高運速度。

  7、減少Mask、spine 等能打斷合並渲染的組件使用。

     8、邏輯比較復雜或者節點較多的界面,采取分幀加載策略,避免一幀內執行過多操作,導致這一幀壓力過大。

  9、優化節點樹,盡量減少節點數量。

  10、如果label內容是字母、常用符號、數字,可以使用位圖bmf,並按需求合並到ui中,避免因為label的穿插渲染導致合並渲染被打斷。

  11、盡量避免頻繁創建與銷毀節點。

  12、合理規划 Material(材質)、Blend(混合模式)的變更(如自定義Shader ),會導致合並渲染被打斷。

    13、降低幀率。

  14、合理使用紋理、數據緩存。

  15、資源優化:

    1.模型的優化
    2.頂點數即面數,要限制。
    3.模型材質大小限制。
    4.動作幀數限制。
    5.模型動畫預創建

  16、盡量不設置_localZOrder < 0 ,  _localZOrder 大於0和小於0的部分被獨立渲染,不會參與批處理。

 

  (注:當采用LocalZOrder作為節點渲染(繪制)順序的判斷值時,父節點的LocalZOrder不與子節點的LocalZOrder值作比較。子節點中LocalZOrder值小於0的節點作為以父節點為根節點的樹的左子樹的根節點,大於0的作為右子樹的根節點。所以在中序遍歷下,先(渲染)繪制子節點中LocalZOrder值小於0的子節點,再渲染(繪制)父節點,再渲染LocalZOrder值大於0的子節點。)

 

  17、降低紋理精度:大張紋理在可接受范圍內減低圖片的部分精度,然后采用縮放。

  18、大量骨骼動畫,可能導致幀率較低,可以考慮在允許的范圍內用幀動畫替換。

 

 

注意以下合理性: 
  
不能無腦的划分資源模塊和使用九宮格,需要考慮DrawCall和頂點數問題,避免造成cpu過多消耗。
 
        
 
        

 

 內存優化:

  1、優化圖集,最大限度填滿圖集,不要留有太多空白

  2、大尺寸的圖片改用九宮格

    3、靜態資源的內存管理:

     靜態資源指的是場景中直接或間接引用到的所有資源(腳本動態加載的資源不算在內)。

     在場景資源的屬性編輯器中可以勾選“自動釋放資源”選項,從而在切換場景時,會自動將舊場景使用的靜態資源釋放掉,從而節省內存的占用。

 

 

   4、動態資源的內存管理:

    動態資源統一使用cc.loader進行資源的加載以及管理。參考:動態加載要注意的一點是,CocosCreator中通過cc.loader去加載資源的所有方法,都是異步的。所以需要在回調中,確認加載完成后才能使用資源。也可以通過cc.loader.getRes這個API去同步的獲取資源,但需要對get到的資源進行檢查,如果沒有加載或者沒有加載完成,則需要等待或者通過cc.loader進行加載。

 

  5、label優化之共用離屏的Canvas(只針對h5、小游戲,代碼以cocos-js 3X為例):

   

//修改CCLabelTTFCanvasRenderCmd.js文件中的文本渲染依賴為共用一個canvas而不是每一次都去創建
 var sharedLabelCanvas = null;

 cc.LabelTTF.CacheRenderCmd = function () {
     this._labelCmdCtor();
   sharedLabelCanvas = sharedLabelCanvas || document.createElement("canvas"); this._labelCanvas = sharedLabelCanvas; this._labelCanvas.getContext("2d").clearRect(0, 0, this._labelCanvas.width, this._labelCanvas.height); this._labelCanvas.width = 1; this._labelCanvas.height = 1; this._labelContext = this._labelCanvas.getContext("2d");
 };

 

   

 


 

手機發熱優化:

  原理:

    手機發熱,無非源於cpu和gpu的過量運算所致,cpu的過載主要由於邏輯運算,GPU的過載更多的由於渲染

 

   優化:

    1.CPU、GPU方面(參考上面)

      3.邏輯方面:降低邏輯復雜度,如按整定時器邏輯觸發頻率、緩存某些常用的復雜邏輯運算結果

      4. 網絡方面:手機的耗電統計中,定位以及網絡連接,都是大戶,而且會引起發熱。如果采用的是長連接的聯網方式,盡量降低數據傳輸的頻次,通訊協議盡量的精簡,心跳的頻率可以適當的大一點,5-10s

 

 


其他優化:

 

    1.壓縮和轉化文理格式(h5安卓可以考慮使用webp可以參考我的另一篇博客:https://www.cnblogs.com/xyptechnology/p/10983233.html

  2.游戲流程優化 參考我的另一篇博客中的流程優化:https://www.cnblogs.com/xyptechnology/p/11996591.html 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM