小程序的邏輯層與渲染層分開在不同的線程運行,這跟傳統的Web 單線程模型有很大的不同,使得小程序架構上多了一些復雜度,也多了一些限制。
[TOC]
### 5.1.1 技術選型
小程序的架構設計時的要求只有一個,就是要快,包括要渲染快、加載快等。當用戶點開某個小程序時,我們期望體驗到的是只有很短暫的加載界面,在一個過渡動畫之后可以馬上看到小程序的主界面。
一般來說,渲染界面的技術有三種:
1. 用純客戶端原生技術來渲染
2. 用純 Web 技術來渲染、
3. 用客戶端原生技術與 Web 技術結合的混合技術(下稱 Hybrid 技術)來渲染
小程序的宿主是微信,所以我們不太可能用純客戶端原生技術來編寫小程序 。如果這么做,那小程序代碼需要與微信代碼一起編包,跟隨微信發版本,這種方式跟開發節奏必然都是不對的。因此,我們需要像Web 技術那樣,有一份隨時可更新的資源包放在云端,通過下載到本地,動態執行后即可渲染出界面。
但,如果用純 Web 技術來渲染小程序,在一些有復雜交互的頁面上可能會面臨一些性能問題,這是因為在 Web 技術中,UI渲染跟 JavaScript 的腳本執行都在一個單線程中執行,這就容易導致一些邏輯任務搶占UI渲染的資源。
以上,使用純客戶端原生技術或純 Web 技術都有各自的缺點,那如果使用兩者結合起來的Hybrid 技術來渲染小程序,能否優于各自獨立渲染的技術方案呢?實際上,這種 Hybrid 技術在業界過去幾年里演化過數種技術方案,
* **PhoneGap**:早期的一個采用HTML,CSS和JavaScript的技術,創建移動跨平臺移動應用程序的框架
* **React Native(下稱 RN)**:近兩年流行的一個 JavaScript 框架,用來編寫原生的 iOS 和 Android 應用。
* **JS-SDK**: 微信公眾平臺面向網頁開發者提供的基于微信內的網頁開發工具包。
最終,小程序選擇類似于微信 JS-SDK 這樣的 Hybrid 技術,即:
`界面`主要由成熟的 Web 技術渲染,輔之以大量的接口提供豐富的客戶端原生能力。同時,每個小程序頁面都是用不同的WebView去渲染,這樣可以提供更好的交互體驗,更貼近原生體驗,也避免了單個WebView的任務過于繁重。此外,界面渲染這一塊我們定義了一套`內置組件`以統一體驗,并且提供一些基礎和通用的能力,進一步降低開發者的學習門檻。值得一提的是,內置組件有一部份較復雜組件是用客戶端原生渲染的,以提供更好的性能。
### 5.1.2 管控與安全
基于Web 技術來渲染小程序是存在一些不可控因素和安全風險的。這是因為Web技術是非常開放靈活的,我們可以利用JavaScript 腳本隨意地跳轉網頁或者改變界面上的任意內容。
為了解決管控與安全問題,我們必須阻止開發者使用一些瀏覽器提供的,諸如跳轉頁面、操作DOM、動態執行腳本的開放性接口。要完全避免JavaScript 的靈活性以及瀏覽器接口的豐富性而帶來的一些危險的接口,或者瀏覽器內核更新而新增的危險接口,小程序提供一個沙箱環境來運行開發者的JavaScript 代碼。
因此,小程序的沙箱環境不能有任何瀏覽器相關接口,只提供純JavaScript 的解釋執行環境,那么像HTML5中的`ServiceWorker`、`WebWorker`特性就符合這樣的條件,這兩者都是啟用另一線程來執行 JavaScript。但是考慮到小程序是一個多 WebView 的架構,每一個小程序頁面都是不同的WebView 渲染后顯示的,在這個架構下不好去用某個WebView中的ServiceWorker去管理所有的小程序頁面。
得益于客戶端系統有JavaScript 的解釋引擎(在iOS下是用內置的 `JavaScriptCore框架`,在安卓則是用騰訊x5內核提供的`JsCore環境`),我們可以創建一個單獨的線程去執行 JavaScript,在這個環境下執行的都是有關小程序業務邏輯的代碼,也就是我們前面一直提到的邏輯層。而界面渲染相關的任務全都在WebView線程里執行,通過邏輯層代碼去控制渲染哪些界面,那么這一層當然就是所謂的渲染層。這就是小程序雙線程模型的由來。
### 5.1.3 天生的延時
小程序是基于雙線程模型,那就意味著任何數據傳遞都是線程間的通信,也就是都會有一定的延時。而傳統Web技術中,當界面需要更新時,通過調用更新接口UI就會同步地渲染出來。在小程序架構里,這一切都會變成異步。
異步會使得各部分的運行時序變得復雜一些。比如在渲染首屏的時候,邏輯層與渲染層會同時開始初始化工作,但是渲染層需要有邏輯層的數據才能把界面渲染出來,如果渲染層初始化工作較快完成,就要等邏輯層的指令才能進行下一步工作。因此邏輯層與渲染層需要有一定的機制保證時序正確,這些工作在小程序框架里會處理好,開發者只需要理解生命周期,以及控制合適的時機更新UI即可。
除了邏輯層與渲染層之間的通信有延時,各層與客戶端原生交互同樣是有延時的。以邏輯層為例,開發者的代碼是跑在邏輯層這個線程之上,而客戶端原生是跑在微信主線程(安卓上是線程)之上,所以注冊給邏輯層有關客戶端能力的接口,實際上也是跟微信主線程之間的通信,同樣意味著有延時。這也是我們看到大部分提供的接口(API)都是異步的原因。
- 微信
- 小程序
- 1. 代碼組成
- 1.1 JSON配置--'*.json'文件
- 1.2 WXML模板--'*.wxml'文件
- 1.3 WXSS樣式--'*.wxss'文件
- 1.4 JavaScript腳本--'*.js'文件
- 2. 客戶端運行
- 2.1 邏輯層和渲染層
- 2.1.1 邏輯層--App Service
- 2.1.2 渲染層/視圖層--View
- 2.1.3 通信模型
- 2.1.4 數據驅動
- 2.1.5 雙線程下的界面渲染
- 2.2 程序與頁面
- 2.3 組件
- 2.4 API
- 2.5 事件
- 2.6 兼容
- 3. 應用設計
- 3.1 Flex布局
- 3.2 界面常見的交互反饋
- 3.3 發起HTTPS網絡通信--wx.request
- 3.4 微信登錄
- 3.5 本地數據緩存
- 3.6 設備能力
- 4. 小程序的協同工作和發布
- 4.1 協同工作
- 4.2 用戶體驗審視
- 4.3 發布
- 4.4 運營
- 5. 底層框架
- 5.1 雙線程模型
- 5.2 組件系統--Exparser框架
- 5.3 原生組件
- 5.4 小程序與客戶端通信原理
- 6. 運行和性能優化
- 6.1 啟動--代碼加載
- 6.2 頁面準備
- 6.3 數據通信
- 6.4 視圖層渲染
- 6.5 原生組件通信
- 7. 小程序基礎庫的更新迭代
- 8. 微信開發者工具
- 騰訊云支持
- wafer
- Wafer2 快速開發 Demo - PHP
- WXAPI
- api列表