一、微信小游戲分包加載機(jī)制
將游戲內(nèi)容拆分成多個(gè)包,在首次啟動(dòng)時(shí)僅下載必要的“主包”,其余分包可在游戲運(yùn)行過程中根據(jù)需要下載。
包大小限制
| 包類型 | 大小限制 | 說明 |
|---|---|---|
| 整個(gè)游戲 | ≤ 30MB | 主包 + 所有分包總和 |
| 主包 | ≤ 4MB | 游戲啟動(dòng)必需的核心資源 |
| 普通分包 | 單個(gè)不限 | 功能模塊,如商城、新關(guān)卡 |
| 獨(dú)立分包 | ≤ 4MB | 可獨(dú)立運(yùn)行的試玩模塊 |
- 整個(gè)小游戲(主包 + 所有分包)總大小不超過 30MB
- 主包大小不超過 4MB
- 單個(gè)普通分包大小不限
- 單個(gè)獨(dú)立分包大小不超過 4MB
獨(dú)立分包
獨(dú)立分包是小游戲中一種特殊類型的分包,可以獨(dú)立于主包和其他分包運(yùn)行。以獨(dú)立分包路徑啟動(dòng)小游戲時(shí),客戶端會(huì)僅下載獨(dú)立分包并啟動(dòng)游戲,不會(huì)下載主包,以此實(shí)現(xiàn)部分場(chǎng)景下快速啟動(dòng)游戲的需求。
開發(fā)者可以按需將某些具有一定功能獨(dú)立性的頁(yè)面配置到獨(dú)立分包中,可以很大程度提高頁(yè)面打開速度。
?? 兩種分包類型對(duì)比
| 特性 | 普通分包 | 獨(dú)立分包 |
|---|---|---|
| 運(yùn)行方式 | 依賴主包運(yùn)行 | 完全獨(dú)立運(yùn)行 |
| 啟動(dòng)速度 | 首次需加載主包 | 極速啟動(dòng),無(wú)需主包 |
| 使用場(chǎng)景 | 游戲主體功能模塊 | 分享試玩、廣告引流 |
| 代碼隔離 | 可調(diào)用主包資源 | 完全隔離,自給自足 |
二、微信小游戲運(yùn)行機(jī)制

在微信里打開一個(gè)小游戲時(shí),過程大概是這樣的:
1. 環(huán)境準(zhǔn)備
當(dāng)點(diǎn)擊小游戲圖標(biāo)的瞬間,微信客戶端會(huì)立刻為這個(gè)游戲:
┌─────────────────────────────────────────┐
│ 微信客戶端(Native層) │
└─────────────────┬───────────────────────┘
│ 啟動(dòng)雙線程模型
┌──────────┴──────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ 邏輯層線程 │ │ 視圖層線程 │
│ │ │ │
│ 創(chuàng)建JS虛擬機(jī) │ │ 創(chuàng)建WebView │
│ │ │ │
│ 注入wx API │ │ 創(chuàng)建Canvas │
└──────────────┘ └──────────────┘
- 啟動(dòng)邏輯層線程:創(chuàng)建一個(gè)全新的 JavaScript虛擬機(jī)(簡(jiǎn)稱JS VM)實(shí)例(在iOS上是 JSContext實(shí)例,Android上是V8實(shí)例)
- 啟動(dòng)視圖層線程:創(chuàng)建一個(gè) WebView 實(shí)例(在iOS上是 WKWebView,Android上是 XWeb),并在其中創(chuàng)建一個(gè)全屏的 Canvas 畫布
- 注入通信橋梁:在邏輯層JS VM中注入 WeixinJSBridge 和 wx API,使其具備與Native層和視圖層通信的能力
?? JavaScript虛擬機(jī)(JS VM)是什么?
JS VM可以理解為是一個(gè)“與世隔絕的JS代碼執(zhí)行牢房,專門用來執(zhí)行JS代碼”。
“與世隔絕”:這是JS VM最關(guān)鍵的一點(diǎn)。這個(gè)牢房沒有門,沒有窗。在牢房里運(yùn)行的JS代碼,無(wú)法直接接觸到外部的任何東西,比如:
- 無(wú)法直接操作手機(jī)的文件系統(tǒng)
- 無(wú)法直接調(diào)用手機(jī)的攝像頭
- 無(wú)法直接發(fā)起網(wǎng)絡(luò)請(qǐng)求
- 甚至無(wú)法知道隔壁牢房(另一個(gè)小游戲)的存在
為什么需要JS虛擬機(jī)?
為了絕對(duì)的安全和穩(wěn)定。
如果小游戲的JS代碼能為所欲為,那么一個(gè)惡意游戲就可以:
- 刪除你手機(jī)上的照片
- 偷偷調(diào)用你的麥克風(fēng)錄音
- 讓另一個(gè)游戲崩潰
- 竊取你在另一個(gè)游戲里的數(shù)據(jù)
JS VM 提供的沙箱環(huán)境從根本上杜絕了這些問題。每個(gè)游戲都在自己的沙箱里玩,誰(shuí)也影響不了誰(shuí)。
?? WeixinJSBridge是什么?
WeixinJSBridge 是那個(gè)“牢房里唯一的內(nèi)線電話”。
既然JS代碼被關(guān)在“牢房”里,它怎么才能實(shí)現(xiàn)登錄、支付、振動(dòng)這些需要與外界交互的功能呢?
答案就是通過這個(gè)唯一的內(nèi)線電話——WeixinJSBridge。它是一個(gè)通信橋梁,連接著隔離的JS VM 和 強(qiáng)大的微信Native層。
“內(nèi)線電話”:JS代碼不能自己“伸手”出去拿東西,但可以通過這個(gè)電話請(qǐng)求外面的“警衛(wèi)”(Native層)幫它做事。
?? 二者的關(guān)系:如何協(xié)作?
JS VM 和 WeixinJSBridge 二者相輔相成共同構(gòu)成了小游戲的安全運(yùn)行體系。
它們的協(xié)作關(guān)系,以及我們開發(fā)者熟悉的 wx API 在其中扮演的角色,可以用下面這張圖清晰地展示:

讓我們用一個(gè)具體例子來走一遍這個(gè)流程:
目標(biāo):小游戲需要振動(dòng)手機(jī)15毫秒。
牢房?jī)?nèi)(JS VM):你的游戲代碼 Game.js 中有一行代碼:
wx.vibrateShort({ type: 'light' });
這里的 wx.vibrateShort 就是你手上的 “電話指令手冊(cè)” (wx API) 里的一條標(biāo)準(zhǔn)指令。
撥打電話(WeixinJSBridge):wx.vibrateShort 這個(gè)API方法的內(nèi)部實(shí)現(xiàn),其實(shí)就是拿起了 “內(nèi)線電話” (WeixinJSBridge),并按照固定格式說:“喂,Native嗎?幫我執(zhí)行一下 vibrateShort 這個(gè)操作,參數(shù)是 {type: 'light'}?!?/p>
牢房外(Native層):微信的Native層(由C++/Java等編寫)接到電話后,真正地去調(diào)用手機(jī)操作系統(tǒng)的振動(dòng)API,讓手機(jī)振動(dòng)起來。
返回結(jié)果:振動(dòng)完成后,Native層再通過 WeixinJSBridge 這個(gè)“電話”回傳給JS VM里的代碼:“事情辦完了。”(通常以一個(gè)回調(diào)函數(shù)或Promise決議的形式通知)。
// 你的游戲代碼中
wx.vibrateShort({ type: 'light' });
// 實(shí)際執(zhí)行流程:
// 1. wx.vibrateShort調(diào)用WeixinJSBridge
// 2. WeixinJSBridge通知微信Native層
// 3. Native層調(diào)用系統(tǒng)振動(dòng)API
// 4. 完成振動(dòng),回調(diào)通知JS層
總結(jié)對(duì)比
| 特性 | JS VM (JavaScript 虛擬機(jī)) | WeixinJSBridge (JS橋接器) |
|---|---|---|
| 角色 | 執(zhí)行環(huán)境(牢房) | 通信工具(電話) |
| 主要功能 | 解釋和執(zhí)行JS代碼,提供安全沙箱隔離 | 在JS環(huán)境和Native環(huán)境之間進(jìn)行安全數(shù)據(jù)通信 |
| 對(duì)開發(fā)者可見性 | 透明,開發(fā)者感知不到它的存在,直接寫JS就行 | 半透明,通常不直接操作它,而是通過封裝好的 wx API來間接使用 |
| 關(guān)系 | 基礎(chǔ):沒有JS VM,JS代碼無(wú)處運(yùn)行 | 通道:沒有WeixinJSBridge,JS代碼與世隔絕,無(wú)法實(shí)現(xiàn)復(fù)雜功能 |
你的小游戲代碼運(yùn)行在 JS VM 這個(gè)安全的沙箱里,并通過 WeixinJSBridge 這個(gè)唯一的橋梁與微信的強(qiáng)大原生能力進(jìn)行通信。
而你平時(shí)打交道的 wx 對(duì)象,則是微信為你封裝好的、用于操作這座橋梁的標(biāo)準(zhǔn)化工具集(wx API)。
關(guān)系:小游戲JS代碼 -> wx API -> WeixinJSBridge -> 微信Native層 -> 操作系統(tǒng)
2、雙線程模型

微信小游戲采用邏輯層與視圖層分離的雙線程模型:
- 邏輯層線程:負(fù)責(zé)執(zhí)行游戲的JavaScript代碼(如Game.js),處理游戲邏輯、數(shù)據(jù)、網(wǎng)絡(luò)請(qǐng)求等
- 視圖層線程:負(fù)責(zé)渲染游戲畫面,本質(zhì)上在小游戲中它只做一件事:管理并繪制一個(gè)Canvas畫布
┌─────────────────────────────────────────┐
│ 微信小游戲架構(gòu) │
├─────────────────────────────────────────┤
│ 邏輯層(大腦) │ 視圖層(畫筆) │
│ │ │
│ ? 執(zhí)行JavaScript代碼 │ ? 管理Canvas畫布 │
│ ? 處理游戲邏輯 │ ? WebGL渲染 │
│ ? 數(shù)據(jù)計(jì)算 │ ? 畫面繪制 │
│ ? 網(wǎng)絡(luò)通信 │ │
└─────────────┬───────────┴────────┬───────┘
│ │
└───事件流與數(shù)據(jù)流────┘
雙線程的具體實(shí)現(xiàn)技術(shù):
| 平臺(tái) | 邏輯層執(zhí)行環(huán)境 | 視圖層渲染環(huán)境 |
|---|---|---|
| iOS微信客戶端 | JavaScriptCore (iOS系統(tǒng)JS引擎) | WKWebView (iOS系統(tǒng)WebView) |
| Android微信客戶端 | V8 (Chrome的JS引擎) | XWeb (微信自研渲染引擎) |
| 微信開發(fā)者工具 | NW.js (桌面JS運(yùn)行時(shí)) | Chromium WebView (Chrome內(nèi)核) |
微信小游戲需要運(yùn)行在iOS、Android、PC等多個(gè)平臺(tái)。微信通過封裝底層差異,開發(fā)者使用的都是同一套JavaScript語(yǔ)言和wx API。
iOS上類似這樣
邏輯層
// JSContext是JavaScriptCore框架中一個(gè)類
JSContext *gameLogicContext = [[JSContext alloc] init]; // 1. 創(chuàng)建一個(gè)JSContext實(shí)例
JSVirtualMachine *jsVM = [gameLogicContext virtualMachine]; // 這就是那個(gè)“JS VM”
// 2. 向這個(gè)JSContext中注入微信的能力
[gameLogicContext setObject: weixinBridgeObject forKeyedSubscript:@"wx"];
// 3. 加載并執(zhí)行你的小游戲代碼
NSString *gameJSCode = ...; // 你的 Game.js 等所有JS代碼
[gameLogicContext evaluateScript: gameJSCode];
視圖層
// 同樣在微信的Objective-C代碼中
WKWebView *gameView = [[WKWebView alloc] initWithFrame: CGRectZero]; // 1. 創(chuàng)建一個(gè)WKWebView
// 2. 加載一個(gè)非常簡(jiǎn)單的HTML頁(yè)面,其中只有一個(gè)<canvas>元素
NSString *htmlString = @"<html><body><canvas id='gameCanvas'></canvas></body></html>";
[gameView loadHTMLString: htmlString baseURL: nil];
// 3. 將gameView的視圖添加到當(dāng)前窗口,但只顯示它的Canvas部分
JS VM = JavaScriptCore 框架。微信用它創(chuàng)建了兩個(gè)實(shí)例。
- 邏輯層線程 = 一個(gè)獨(dú)立的 JSContext實(shí)例,運(yùn)行你的 Game.js
- 視圖層線程 = 一個(gè)隱藏的 WKWebView 實(shí)例,負(fù)責(zé)渲染Canvas
-
WeixinJSBridge = 一整套 Objective-C 與 JavaScript 互相調(diào)用的技術(shù)實(shí)現(xiàn),包括:
- 向 JSContext 注入Native對(duì)象
- 使用 WKWebView 的 evaluateJavaScript: 和 messageHandlers
正是通過這種精妙的設(shè)計(jì),微信在iOS平臺(tái)上將蘋果官方的組件粘合起來,構(gòu)建出了與抽象架構(gòu)完全一致的雙線程安全模型。
Android的實(shí)現(xiàn)雖然技術(shù)細(xì)節(jié)不同(用V8代替JSCore,用XWeb代替WKWebView),但最終的架構(gòu)和行為是完全一致的。
3. 下載與加載

環(huán)境準(zhǔn)備好后,開始加載游戲內(nèi)容:
下載游戲包:微信客戶端根據(jù)你的地理位置,從最近的CDN節(jié)點(diǎn)按需下載游戲包。為了速度,它通常不會(huì)一次性下載全部,而是先下載一個(gè)核心啟動(dòng)包(game.js 和必要的框架代碼)
-
加載引擎與代碼:
- 首先加載小游戲適配器和游戲引擎的框架代碼(如Cocos引擎庫(kù)或Unity的WebAssembly模塊和膠水代碼)
- 然后加載你的業(yè)務(wù)邏輯代碼(如 src 目錄下的 Game.js, Player.js 等)
緩存到本地:下載的文件會(huì)被緩存在手機(jī)本地,下次打開游戲時(shí)極大減少下載時(shí)間
4. 初始化與啟動(dòng)
所有代碼就位后,啟動(dòng)開始:
引擎初始化:執(zhí)行引擎框架的初始化代碼,引擎會(huì)通過
wx.createCanvas()獲取Canvas畫布,初始化WebGL上下文執(zhí)行Game.js:這是小游戲的入口文件。微信客戶端會(huì)主動(dòng)調(diào)用其中定義的
onLaunch和onShow生命周期函數(shù)-
游戲主循環(huán)開始:
- 你的游戲代碼(例如Cocos的
cc.game.run)開始執(zhí)行,啟動(dòng)游戲主循環(huán) - 邏輯層(JS VM)開始計(jì)算游戲世界狀態(tài):角色位置、物理碰撞、分?jǐn)?shù)等
- 視圖層(WebView)根據(jù)邏輯層傳來的數(shù)據(jù),通過WebGL在Canvas上繪制出一幀幀畫面
- 你的游戲代碼(例如Cocos的
事件循環(huán):同時(shí),微信客戶端會(huì)持續(xù)將用戶的觸摸、手機(jī)傳感器等事件,通過WeixinJSBridge傳遞給邏輯層,邏輯層處理后再觸發(fā)視圖層更新
總結(jié)一下:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 下載 │───?│ 加載 │───?│ 啟動(dòng) │
├─────────┤ ├─────────┤ ├─────────┤
│ 1. 就近CDN │ │ 1. 引擎框架 │ │ 1. 引擎初始化 │
│ 2. 核心啟動(dòng)包│ │ 2. 業(yè)務(wù)代碼 │ │ 2. 執(zhí)行Game.js│
│ 3. 智能緩存 │ │ 3. 資源預(yù)載 │ │ 3. 游戲主循環(huán)│
└─────────┘ └─────────┘ └─────────┘
啟動(dòng)詳細(xì)流程:
- 智能下載:從最近CDN下載最小必要資源包
-
分層加載:
- 先加載引擎適配器
- 再加載游戲業(yè)務(wù)代碼
- 緩存優(yōu)化:下載內(nèi)容本地緩存,二次啟動(dòng)極速
-
初始化:
// 微信自動(dòng)調(diào)用Game.js生命周期 GameGlobal.onLaunch(); // 游戲初始化 GameGlobal.onShow(); // 游戲顯示 -
主循環(huán)開始:
- 邏輯層計(jì)算游戲狀態(tài)
- 視圖層渲染每一幀
- 事件系統(tǒng)處理用戶交互
三、CocosCreator、Unity不同游戲引擎開發(fā)的游戲?yàn)樯赌苓\(yùn)行在微信小游戲平臺(tái)?
游戲引擎的構(gòu)建發(fā)布過程,不是簡(jiǎn)單的打包,而是一次深度的代碼轉(zhuǎn)換和接口對(duì)接。

1. Cocos Creator (TypeScript/JavaScript)
Cocos Creator 的轉(zhuǎn)換過程最為“自然”,因?yàn)樗旧砭褪褂?TypeScript/JavaScript。
- 代碼層面:你寫的 .ts 腳本在構(gòu)建時(shí),會(huì)被編譯成優(yōu)化后的 .js 文件。這部分代碼可以直接在小游戲的JS VM中運(yùn)行
- 引擎層面:Cocos Creator 引擎庫(kù)本身的代碼(也是用 TypeScript 寫的)也會(huì)被編譯成 JavaScript,并一起發(fā)布
-
適配層:這是關(guān)鍵!Cocos Creator 內(nèi)置了一個(gè) “微信小游戲適配器”。這個(gè)適配器做了以下核心工作:
-
畫布創(chuàng)建:使用
wx.createCanvas()創(chuàng)建游戲畫布,而不是瀏覽器中的<canvas>元素 -
資源加載:將引擎內(nèi)的
cc.assetManager等資源加載請(qǐng)求,轉(zhuǎn)譯成wx.request或wx.downloadFile等小游戲API -
文件系統(tǒng):將引擎的文件操作適配到小游戲的本地文件系統(tǒng)
wx.getFileSystemManager() -
輸入事件:將
wx.onTouchStart等事件,轉(zhuǎn)換成 Cocos Creator 引擎能識(shí)別的cc.systemEvent -
音頻播放:將
cc.audioEngine.play轉(zhuǎn)成wx.createInnerAudioContext()
-
畫布創(chuàng)建:使用
┌─────────────────────────────────────────────┐
│ Cocos Creator開發(fā)流程 │
├─────────────────────────────────────────────┤
│ 你的TypeScript代碼 → 編譯優(yōu)化 → .js文件 │
│ │
│ Cocos引擎庫(kù) → 編譯優(yōu)化 → 引擎.js │
│ │
│ ╭──────────────────────────────────────╮ │
│ │ 微信小游戲適配器(關(guān)鍵橋梁) │ │
│ ├──────────────────────────────────────┤ │
│ │ ? 畫布創(chuàng)建:wx.createCanvas() │ │
│ │ ? 資源加載:wx.request() │ │
│ │ ? 文件系統(tǒng):wx.getFileSystemManager() │ │
│ │ ? 音頻播放:wx.createInnerAudioContext()│ │
│ │ ? 輸入事件:適配觸摸到cc.systemEvent │ │
│ ╰──────────────────────────────────────╯ │
└─────────────────────────────────────────────┘
優(yōu)勢(shì):TypeScript原生支持,轉(zhuǎn)換自然,性能損耗小
結(jié)果:你寫的游戲邏輯代碼幾乎不用改,因?yàn)橐婧瓦m配器幫你處理了所有平臺(tái)差異。
2. Unity (C#)
Unity 的轉(zhuǎn)換過程更為復(fù)雜,因?yàn)樗婕皬?C# 到 JavaScript 的“跨界”轉(zhuǎn)換。
核心技術(shù):IL2CPP 與 WebAssembly
C#到C++:發(fā)布小游戲時(shí),Unity 會(huì)使用 IL2CPP 技術(shù),將你的 C# 代碼和 Unity 引擎底層代碼編譯成 C++
C++ 到 WebAssembly:再將生成的 C++ 代碼編譯為 WebAssembly 字節(jié)碼。WASM 是一種可以在現(xiàn)代瀏覽器(包括小游戲的WebView)中高效運(yùn)行的低級(jí)語(yǔ)言,性能接近原生
JavaScript 膠水代碼:Unity 會(huì)生成大量的 JavaScript “膠水代碼”,這些代碼負(fù)責(zé):
- 加載和實(shí)例化 WASM 模塊
- 在 小游戲的JS VM 和 WASM模塊 之間建立通信橋梁
- 將 Unity 的渲染命令(如 OpenGL)轉(zhuǎn)發(fā)給小游戲的 Canvas(通過 WebGL)
- 將小游戲平臺(tái)接收到的事件(觸摸、傳感器等)傳遞給 WASM 模塊中的游戲邏輯
適配層:與 Cocos 類似,Unity 也有一個(gè)針對(duì)微信小游戲的 Platform Abstraction Layer。它實(shí)現(xiàn)了 Unity 引擎期望的系統(tǒng)調(diào)用(如文件I/O、網(wǎng)絡(luò)、音頻)在微信平臺(tái)上的具體實(shí)現(xiàn),內(nèi)部同樣是調(diào)用了 wx.* 系列 API。
┌─────────────────────────────────────────────┐
│ Unity到微信小游戲轉(zhuǎn)換流程 │
├─────────────────────────────────────────────┤
│ 你的C#代碼 + Unity引擎 │
│ ↓ │
│ IL2CPP技術(shù)轉(zhuǎn)換 │
│ ↓ │
│ C++中間代碼生成 │
│ ↓ │
│ 編譯為WebAssembly字節(jié)碼 │
│ ↓ │
│ 生成JavaScript膠水代碼 │
│ ╭──────────────────────────────────────╮ │
│ │ 微信平臺(tái)適配層(PAL) │ │
│ ├──────────────────────────────────────┤ │
│ │ ? 實(shí)現(xiàn)Unity引擎期望的系統(tǒng)接口 │ │
│ │ ? 映射到wx.*系列API │ │
│ │ ? 處理渲染命令轉(zhuǎn)發(fā) │ │
│ │ ? 橋接WASM與JS環(huán)境 │ │
│ ╰──────────────────────────────────────╯ │
└─────────────────────────────────────────────┘
關(guān)鍵技術(shù):
- WebAssembly:高性能字節(jié)碼,接近原生性能
- JavaScript膠水代碼:連接WASM模塊與微信環(huán)境
- 平臺(tái)抽象層:統(tǒng)一接口,屏蔽平臺(tái)差異
結(jié)果:點(diǎn)擊“發(fā)布為微信小游戲”,Unity就幫你完成了一系列復(fù)雜的轉(zhuǎn)換和適配,生成一個(gè)可以直接在微信里運(yùn)行的包。
總結(jié):微信小游戲的設(shè)計(jì)
微信小游戲通過四大核心技術(shù)實(shí)現(xiàn)了安全、高性能的游戲體驗(yàn):
- 分包加載機(jī)制 - 按需下載,平衡體驗(yàn)與內(nèi)容
- 雙線程模型 - 邏輯渲染分離,保障流暢穩(wěn)定
- 安全沙箱 - JS虛擬機(jī)確保平臺(tái)安全
- 統(tǒng)一適配層 - 讓不同引擎游戲無(wú)縫運(yùn)行
這套機(jī)制讓開發(fā)者只需關(guān)注游戲內(nèi)容創(chuàng)作,復(fù)雜的底層適配和性能優(yōu)化由微信平臺(tái)和游戲引擎共同完成,真正實(shí)現(xiàn)了"一次開發(fā),多端運(yùn)行"的理想狀態(tài)。