本篇雖然是源自於處理遊戲產業FPS的效能問題,但事後覺得大部分其實通用在各個產業,所以還是分享了出來。
在遊戲產業的效能,就讓我們先從FPS (Frame Per Second — 每秒顯示影格數) 開始說起吧!
畫面的顯示,其實都是在連續播放一幀幀的影像,當播放速度越快,人眼因視覺暫留所感受到的也會是更順暢的表現,而人眼一般覺得順暢的FPS是每秒24幀,但數字越大、讓越敏感的人眼也還是會感到順暢;
雖然聽起來只要讓遊戲的FPS可以在24就好,但有時候還是會受記憶體、硬體等限制而影響,所以其實FPS是越高越好!
再來呢,就讓我們來看看,能從哪些方面開始著手處理效能。
檢查效能的方法 & 對應的調整
方法1 → 打開 DevTools > performance,錄製一段你想檢查的範圍,接著查看code stack
參考連結:https://developer.chrome.com/docs/devtools/performance/
- 確認是否有某個function執行過久
- 確認是否有變數的記憶體空間沒有釋放出來並且隨著重複執行而無限堆疊
方法2 → 安裝並使用 webpack-bundle-analyzer,縮減bundle size
- 如果有外部共用的plugin,可以將它分離於專案,以縮減網頁載入時會在同一個文檔載入過久的問題
- 如果有用不到的plugin也被打包起來,可以將它移除安裝或是不import
- 如果有會用到plugin中的指定function,可視情況改成只提取引入單一function
/* 常見的寫法 */
import _ from 'lodash';
_.cloneDeep(values)
/* 可調整成 */
import { cloneDeep } from 'lodash';
cloneDeep(values)
方法3 → trace 專案的 code,減少不必要的資源浪費
- 確認是否有 `時間/空間複雜度相較高的function` 可以改寫成較有效率的執行方式
- 有些東西可以改用singleton (e.g. call api的instance)
- 確認是否有些資源可以動態判斷並載入 (e.g. 因為safari iOS不支援Media Source Extensions,所以動態判斷裝置以決定是否要載入並使用flvjs來進行視頻的播放)
- 有些東西可以用debounce包起來,減少短時間內的大量重新渲染 (e.g. 表單的輸入框、RWD callback)
- 在webpack打包的過程中,對import路徑的大小寫不太敏感,可能會導致同份檔案打包了2次 (build完之後看原始碼會可以知道)
方法4 → 針對遊戲引擎進行效能研究
這邊的遊戲引擎是 Pixi.js,僅供參考
- 針對不常變動的元件進行cacheAsBitmap (e.g. 若是常用到的請不要設定,避免造成資源更容易消耗)
- 有多個stage時,可以針對用不到的stage進行隱藏 (e.g. 網路上還有流傳一種說法是將position移到畫布之外也可以XD)
- 當網頁進入背景模式時就卸載一切,可以將場景切換為空
以上是我在效能調教這路上的小小心得 ^_^
(也感謝夥伴們一起努力💪🏻)
雖然效能好像沒有調教完美的那刻,但還是祝大家都可以順利擊敗大魔王!!