如果文章有誤解的地方,歡迎指出,將在第一時間改正,有更好的實現方式希望留下你的評論!
優化內容:游戲包體積,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