一文搞定 Cocos 微信小游戲分包策略
共 8181字,需瀏覽 17分鐘
·
2024-05-09 09:17
歡迎預約
Error: 系統(tǒng)錯誤,錯誤碼:80051,source
size 9424KB exceed max limit 4MB
相信 90% 的朋友第一次發(fā)布小游戲時,都會遇上首包限制的問題。社區(qū)中有非常多關于如何減少首包大小的文章,但在 Cocos Creator 3.8 版本發(fā)布之后,引擎自帶分包功能已經非常強大,在不改動引擎機制的情況下,就足以應對常見項目需求。
今天我們就以 Cocos Creator 自帶的 Hello World 為例,一步步實現(xiàn)包體優(yōu)化,最終效果如下:
| 項目 | 優(yōu)化后 | 優(yōu)化前 |
|---|---|---|
| 總包大小 | 3.73MB | 9.22MB |
| 主包大小 | 2.14MB | 9.22MB |
| 分包大小 | 1.59MB | 9.22MB |
| cocos-js | 1.68MB | 3.95MB |
| 包數(shù)量 | 2 | 1 |
具體情況可以點開下圖查看:
接下來,我們從新建項目開始,一步步優(yōu)化。
-
1.引擎裁剪 -
2.分包設置 -
3.資源引用剔除 -
4.大文件排查 -
5.WASM 分離
一、新建項目
-
新建項目面板,版本選擇 Cocos Creator 3.8.2(建議用最新版本),模板選擇 “Hello World”,即可創(chuàng)建帶有素材的測試項目。
-
不做任何修改,發(fā)布到微信小游戲
-
用微信開發(fā)者工具打開,選擇“代碼依賴分析”,可以看到如下數(shù)據(jù)
我們可以看到它只有一個主包,總包大小已經 9.22 MB了,不做處理肯定是不行的。
二、引擎裁剪
定位到主菜單 -> 項目 -> 項目設置 -> 功能裁剪。
可以看到這里面提供了許多可選項。我們移除 WebGL 2.0、視頻、Webview、Marionette 動畫系統(tǒng)、基礎幾何體、地形、光照探針、2D 物理系統(tǒng)、2D 粒子系統(tǒng)、Tiled 地圖、Spine 動畫、Dragon Bones、WebSocket。
WebSocket 是針對原生平臺的選項,小游戲和 Web 平臺可以都去掉,不影響 WebSocket 使用
以上移模塊除后,就是一個常見 3D 項目所需的基礎模塊了。
“實際上,在這個例子中,
”音頻、緩動系統(tǒng)、3D 物理系統(tǒng)、3D 粒子系統(tǒng)因為并沒有使用,都是可以移除的。但我們作為測試,盡可能保留大部分項目都需要用到的模塊,才能符合商業(yè)項目需求。
總的來說就是:把不需要的模塊都移除掉。
再次發(fā)布到微信小游戲,可以看到下面的結果:
| 項目 | 優(yōu)化后 | 優(yōu)化前 |
|---|---|---|
| 總包大小 | 7.61MB | 9.22MB |
| 主包大小 | 7.61MB | 9.22MB |
| cocos-js | 2.46 MB | 3.95MB |
一般的項目,都會帶有許多游戲素材,光是裁剪肯定是不夠的。接下來,我們通過分包設置,將游戲內容從主包里分離。
三、分包設置
3.1 調整目錄
新建一個 game 文件夾,然后把所有其它文件都拖進去,最終目錄結構如下:
拖進去后,如果發(fā)現(xiàn) material 和 model 文件夾有殘留,直接刪除即可。
3.2 設置分包
選中 game 目錄,做以下操作:
-
在右邊的屬性面板中,選擇配置為 Bundle -
點擊“編輯”按鈕,打開 Bundle 配置面板 -
勾選“單獨配置” -
微信小游戲一欄選擇“小游戲分包” -
點擊“保存”
這樣一來,分包就設置好了。
3.3 制作加載場景
分包不會自動加載,因此,我們需要制作一個場景用于加載。
-
在 assets 目錄下新建場景起名為 "start" -
在 assets 目錄下新建一個腳本起名為 "Start" -
在 Start.ts 中編寫如下代碼
assetManager.loadBundle("game",(err,bundle:AssetManager.Bundle)=>{
director.loadScene("main");
});
-
在 start 場景中,新建一個空節(jié)點,起名為 Start -
將 Start.ts 組件掛上去 -
在 start 場景上放一個小 Logo,以避免什么都沒有顯示
最終的項目目錄和畫面可能如下:
在構建面板,將剛剛新建的 start 場景選擇為啟動場景,再次打包,可以在微信小游戲開發(fā)工具中看到如下數(shù)據(jù):
| 項目 | 優(yōu)化后 | 優(yōu)化前 |
|---|---|---|
| 總包大小 | 9.94MB | 7.61MB |
| 主包大小 | 4.02MB | 7.61MB |
| 分包大小 | 5.92MB | - |
| cocos-js | 2.47 MB | 2.46MB |
可以看到,在優(yōu)化后,雖然主包下降了,但總包大小上升了。
這里就得提到一個隱含的重要知識點了。Cocos Creator 有以下幾種包:
| 類型 | 優(yōu)先級 | 用途 | 資源引用方式 |
|---|---|---|---|
| internal | 21 | 內置資源 | 僅打包已使用資源 |
| resources | 8 | 內置 bundle | 打包所有資源 |
| main | 7 | 主包 | 僅打包已使用資源 |
| bundle | 1+ | 普通分包 | 打包所有資源 |
Bundle 優(yōu)先級
assets 目錄下的資源,如果不處于 bundle 中( resources 是一個內置的bundle,行為和普通 bundle 一致)時,則僅會將使用過的資源入對應的bundle包。
-
當被多個不同優(yōu)先級的包同時引用時,打入優(yōu)先級最高的那個包。 -
當被多個相同優(yōu)先級的包同時引用時,會每個包都打入。
對于內置 bundle,internal, resources, main 來說,優(yōu)先級還決定了加載順序。可以看出, resources 會比 main 先加載。因此,應該盡量避免在 resources 目錄放置過多內容,大型項目可以直接避免使用 resources 目錄。
四、資源引用剔除
有了以上的 Bundle 和優(yōu)先級相關的知識后,我們可以知道,Bundle 中只需要放以下幾個內容:
-
需要的場景 -
需要動態(tài)加載的素材(Prefab、圖片、動畫、音頻等)
對于不需要動態(tài)加載的,我們通過場景引用,引擎會自動幫我們處理好資源關系。
接下來,我們新建一個 res 目錄,并且把 game 目錄下除 scene 以外的文件夾移動過去,得到的目錄結構如下:
| 項目 | 優(yōu)化后 | 優(yōu)化前 |
|---|---|---|
| 總包大小 | 8.50MB | 9.94MB |
| 主包大小 | 4.02MB | 4.02MB |
| 分包大小 | 4.48MB | 5.92 |
| cocos-js | 2.47 MB | 2.47MB |
可以發(fā)現(xiàn),包體大小還是不夠理想,那么我們就要來具體分析占用包體較大的文件。
主包排查
通過查看分布圖,我們可以發(fā)現(xiàn),主包除了代碼外,assets 目錄還占用了 1.36 MB。而我們放的 logo.jpg 只有 41 KB,顯示是超出預期的。
定位到對應文件夾后,發(fā)現(xiàn)是一堆天空盒貼圖:
這就好辦了!
由于我們的 start 場景不需要顯示天空盒,所以只需要去除這個引用就行。
-
打開 start 場景
-
關閉場景面板上的 Skybox,移除場景面板上的天空盒引用
-
Main Camera 的 ClearFlags 設置為 SOLID_COLOR
再次發(fā)布版本,可以看到主包數(shù)據(jù)變化:
| 項目 | 優(yōu)化后 | 優(yōu)化前 |
|---|---|---|
| 總包大小 | 7.66MB | 8.50MB |
| 主包大小 | 3.19MB | 4.02MB |
| 分包大小 | 4.48MB | 4.48MB |
| cocos-js | 2.47 MB | 2.47MB |
可以看到,最終我們得到了 7.66 MB 的總包大小,并且主包控制在了 3.19 MB。已經可以滿足我們的需求。
但這并非結束,甚至,優(yōu)化才剛剛開始。
大文件排查
通過依賴分析圖,我們可以看到子包里的 native 有 3.99 MB 占用。
native 下一般是圖片為主,我們定位到目錄中可以看到是 Hello World 中使用的天空盒。
在 Cocos Creator 中查看,可以看到它有 4096 x 3072 這么大
對于這個天空盒,根本不需要這么高的精度,通過圖片工具,直接將它改為 1024 x 768。
同時,我們發(fā)現(xiàn) seafloor,stone 等分辨率,是可以縮小一倍的。
雖然可以使用 tinypng 等工具對圖片進行壓縮,但建議在壓縮之前調整好合理的分辨率,能夠降低內存開銷。
將這些素材處理好之后,再次打包。
| 項目 | 優(yōu)化后 | 優(yōu)化前 |
|---|---|---|
| 總包大小 | 4.77MB | 7.66MB |
| 主包大小 | 3.19MB | 3.19MB |
| 分包大小 | 1.59MB | 2.18MB |
| cocos-js | 2.47 MB | 2.47MB |
WASM 分離
雖然主包已經控制在了 3.19 MB。但如果我們要同時開啟 Spine,Box2D 等功能,或者要在 start 場景里加載一些資源, 0.81 MB 的空間還是略顯拮據(jù)。
因此,引擎在小游戲打包時,提供了 WASM 分離功能。所有開啟了 WASM 的模塊,都會在打包時,放入子包,以減少主包占用。
勾選后再次打包,可以看到:
| 項目 | 優(yōu)化后 | 優(yōu)化前 |
|---|---|---|
| 總包大小 | 5.39MB | 5.37MB |
| 主包大小 | 2.70MB | 3.19MB |
| 分包1大小 | 1.59MB | 1.59MB |
| 分包2大小 | 463KB | - |
| 分包3大小 | 57KB | - |
| cocos-js | 1.99 MB | 2.47MB |
3D 項目極限嘗試
其實有許多 3D 項目和這個 HelloWorld 一樣,不需要物理,也不需要 3D 粒子系統(tǒng),那么可能是如下數(shù)據(jù):
2D 項目極限嘗試
如果你是一個 2D 項目,需要 Spine,但是不需要物理、2D 粒子等。
Cocos Creator 可以做到主包 1.94 MB,cocos-js 1.64 MB。
如果覺得默認的配置還不夠滿意,可以自己進一步裁剪引擎,達到最小化功能。
分包常用知識
-
小游戲分包可以包含代碼 -
遠程包不可以包含代碼,如果將包含代碼的包設置為遠程包,則代碼會自動被抽離 -
非 ZIP 格式的分包,在調用 assetManager.loadBundle 時,只會加載資源列表,不會加載所有資源 -
ZIP 格式的分包,會在第一次加載完成后解壓,后面的加載請求會從緩存中讀取 -
分包內的代碼,在加載完成后自動裝載執(zhí)行,但是卸載分包不會卸載代碼
附1:小游戲分包機制
隨著小游戲的玩法越來越豐富,開發(fā)者對于擴大包大小的需求越來越強烈,所以眾多小游戲平臺都推出了分包加載這一個功能。
所謂的分包加載,即把游戲內容按一定規(guī)則拆分這幾包,在首次啟動時先下載必要的包,這個必要的包我們稱為「主包」,開發(fā)者可以在主包內觸發(fā)其它分包的下載,從而把首次啟動的下載耗時分散到游戲運行中。
附2:分包限制
目前小游戲分包大小有以下限制:
-
整個小游戲所有主包+分包大小不超過 20M(開通虛擬支付后的小游戲不超過30M) -
主包不超過 4M -
單個普通分包不限制大小,但受總包大小限制 -
單個獨立分包不超過 4M
“獨立分包是小游戲中一種特殊類型的分包,可以獨立于主包和其他分包運行,對于一些大廳子游戲玩法的游戲很好用,今天暫不討論。
”
希望這篇文章能夠幫助到大家!
回頭這篇文章會以“最佳實踐”納入官方文檔,也希望各位開發(fā)者提交最佳實踐相關文章 PR 到官方文檔倉庫。
往期推薦
Cocos Creator 3.x 如何完美的獲取遠程Bundle加載進度
歡迎關注 Cocos 官方公眾號
