微信小程序架構(gòu)解析,你懂了么?

前言:

?????? 隨著微信小程序日漸發(fā)展和繁榮,相信不少的前端開發(fā)者寫不過不少的微信小程序應(yīng)用。那么,在應(yīng)用開發(fā)之余,你是否也同樣好奇小程序框架本身的一些實(shí)現(xiàn)原理。今天,讓我們一起徜徉探索小程序的誕生和架構(gòu)的原理。

一、微信小程序的誕生

??????小程序是期望的產(chǎn)物。H5 頁面的推廣方式比較多,但同時(shí)H5 也有自己的缺點(diǎn),無法自己獲取很多底層 APP 擁有的功能。隨著微信推出微信公眾號(hào),并提供一系列的 JS-SDK 給 Web 開發(fā)使用, Web 開發(fā)者擁有可以使用到微信的原生能力后, WebView 的使用頻率越來越高。而Webview 的加載體驗(yàn)相對(duì)比較糟糕。微信作為一個(gè)平臺(tái),具有優(yōu)化用戶體驗(yàn)的責(zé)任。那么平臺(tái)如何優(yōu)化這種用戶體驗(yàn)?而作為一個(gè)平臺(tái),又如何保證平臺(tái)不被濫用呢?小程序就是在這種期待中誕生的。一方面,小程序是基于 WebView 開發(fā)的,其目的是減少開發(fā)的成本,實(shí)現(xiàn)異步加載的方式,允許開發(fā)者在線的版本更新和 Bug 修復(fù)。而 前面說的 使用 Webview 容易導(dǎo)致加載體驗(yàn)不好,小程序使用了雙線程的方式來使頁面渲染和邏輯代碼加載分開,降低頁面卡殼的可能性。同時(shí),小程序提供了基礎(chǔ)能力,提供原生組件,讓用戶可以獲得原生應(yīng)用的體驗(yàn)。另一方面呢,微信平臺(tái)通過平臺(tái)發(fā)布、審核、下架等封禁能力,實(shí)現(xiàn)對(duì) 小程序的管控,保護(hù)了平臺(tái),防止平臺(tái)被濫用。

二、小程序的架構(gòu)原理

??????前面提到使用了雙線程的方式來使頁面渲染和邏輯代碼分開加載,那么小程序具體是怎么實(shí)現(xiàn)的呢?下面我們來一起來探索小程序的架構(gòu)設(shè)計(jì)。

??????小程序采用雙線程管理模式。首先貼一下微信小程序的架構(gòu)圖。
image.png

??????微信小程序的框架包含兩個(gè)部分,分別為視圖渲染View 層 和代碼邏輯 AppService層。視圖渲染層用于渲染頁面結(jié)構(gòu),代碼邏輯層用于運(yùn)行 JS 腳本。視圖層和 邏輯代碼層采用了雙線程方式進(jìn)行管理。視圖層運(yùn)行于一個(gè) Webview 線程。在 Webview 線程中,會(huì)將 wxml 轉(zhuǎn)化成 html, 將 wxss 轉(zhuǎn)化為 css,最終展示成我們的視圖。代碼邏輯層運(yùn)行在另一個(gè) Webview 線程,即 JS 執(zhí)行引擎線程(不同的環(huán)境中,實(shí)現(xiàn)的引擎不一樣,在 IOS 中,使用 JavaScriptCore , 在 安卓中使用 V8 引擎或者 x5 JS 解析器,在 開發(fā)工具中,使用 nwjs Chrome 內(nèi)核 ,我們統(tǒng)稱為 JSCore)。在 Jscore 中,提供了 javaScript 的運(yùn)行環(huán)境,在這個(gè)線程中執(zhí)行小程序主要執(zhí)行小程序的邏輯代碼。而視圖層和代碼邏輯層是兩個(gè)單獨(dú)的執(zhí)行線程,而這兩個(gè)線程之間的通信則是通過我們的 JSBridge。

??????以上,我們從整體介紹了小程序的整個(gè)架構(gòu),下面根據(jù)不同部分再進(jìn)行簡單地剖析。

視圖渲染View 層

??????視圖層是運(yùn)行于 Webview 線程中的。我們首先從開發(fā)者工作具調(diào)試-> 調(diào)試-> 調(diào)試開發(fā)者工具進(jìn)入查看調(diào)試代碼時(shí)可以發(fā)現(xiàn)這一點(diǎn)。如下圖:

image (1).png

image (2).png

??????如上圖可明顯可知,小程序運(yùn)行時(shí)是將整個(gè)視圖轉(zhuǎn)化成 我們平常熟悉的 html + css 格式的。而我們平常開發(fā)的視圖展示則是用 一個(gè) webview 中的 iframe 去承載。
我們通過下面這行代碼可以打開對(duì)應(yīng)的 webview 視圖層的代碼。

document.getElementsByTagName('webview')[0].showDevTools(true,null)

打開如下:

image (3).png

??????可以發(fā)現(xiàn)iframe 承載的內(nèi)容實(shí)際是 一個(gè) html ,他的標(biāo)簽是類似于 web component 的組件形式,而小程序識(shí)別這些標(biāo)簽則是通過小程序的基礎(chǔ)庫去進(jìn)行識(shí)別解析。

??????我們知道我們平常開發(fā)微信小程序視圖層代碼是編寫 WXML 和 WXSS。那么小程序是如何將 WXML 和 WXSS 轉(zhuǎn)換成 hmtl 和 css 的呢?這也是通過小程序的基礎(chǔ)庫去進(jìn)行的。我們通過開發(fā)者工具 -> 調(diào)試 -> 打開調(diào)試目錄 -> 公共庫目錄 ,即可以打開我們的基礎(chǔ)庫目錄。如下,其中2.04.wxvpkg 和 2.16.0.wxvkpg 為不同版本的基礎(chǔ)庫,其他的為一些其他的相關(guān)文件。

image (4).png

其中有兩個(gè)運(yùn)行腳本,wcc 和 wcsc。
解開基礎(chǔ)庫wxvpkg文件之后得到的如下文件。


image (5).png

我們重點(diǎn)關(guān)注

  • WAWebview.js
  • WAService.js

??????使用 wcc 可以將 wxml 文件編譯為 js 文件,該js 文件有全局的 gwx 函數(shù),調(diào)用gwx 函數(shù) 最后會(huì)生成 Virtual dom 的對(duì)象 ,最后交給 WAWebview.js 去進(jìn)行渲染生成html。
使用 wcsc 可以將 wxss 文件變?yōu)?js 文件,最后js 運(yùn)行時(shí)渲染成 css。
以上,便是我們此次對(duì)于 視圖 View 層渲染的一些簡單解析。

邏輯層JSCore 層

??????邏輯層 JScore 層的部分則是 JS 在線程的運(yùn)行,沒有相對(duì)視圖層的視圖解析。在邏輯層,主要是將數(shù)據(jù)進(jìn)行處理之后發(fā)給視圖層,同時(shí)也接受視圖層的事件反饋。在邏輯層,主要實(shí)現(xiàn)的功能是 初始化了應(yīng)用程序,提供原生功能 api。上面基礎(chǔ)庫文件,WAService.js 是運(yùn)行在 JScore 層的js 文件。在該文件中實(shí)現(xiàn)的模塊主要是:
1、WeixinJSBridge 兼容模塊
2、 Reporter 模塊。
3、比 WAWebview.js 中 wx 功能更為豐富 wx 接口模塊。(剩余部分 wx api 都在這里)
4、appServiceEngine 模塊,提供 Page,App,GetApp 接口,
5、為 window 對(duì)象添加 AMD 接口 require define

在該文件中實(shí)現(xiàn)的只要功能則是:
1、App( ) 小程序的入口;Page( ) 頁面的入口
2、wx API;
3、頁面有的作用域,提供模塊化能力
4、數(shù)據(jù)綁定、事件分發(fā)、生命周期管理、路由管理

以上,是對(duì)邏輯層的一些簡單補(bǔ)充說明。

視圖View層 和 邏輯JScore 層的通信

??????視圖層和邏輯層之間的通信是通過 Native (微信客戶端)做中轉(zhuǎn)的。通過使用publish和subscribe機(jī)制來進(jìn)行兩個(gè)線程之間的通信。而具體的實(shí)現(xiàn)方式就是統(tǒng)一封裝一個(gè)WeixinJSBridge。視圖層封裝了WeixinJSBridge ,邏輯層也同樣也兼容了 WeixinJSBridge 的模塊,而不同環(huán)境的封裝的接口則不太一樣。對(duì)于 windows 環(huán)境,主要是通過window.postMessage實(shí)現(xiàn)。對(duì)于 IOS ,則主要是通過 WKWebview的window.webkit.messageHandlers.NAME.postMessag。而對(duì)于 安卓,則是通過WeixinJSCore.invokeHanlder。當(dāng)視圖層有事件需要反饋給邏輯層的時(shí)候,會(huì)調(diào)用 WeixinJSBridge ,最終通知給邏輯層,而邏輯層有數(shù)據(jù)更新需要通知給視圖層的時(shí)候,也一樣會(huì)調(diào)用 WeixinJSBridge,將數(shù)據(jù)反饋給 視圖層所以一次完整的用戶事件可大致如下:
1、渲染層 -> Native (點(diǎn)擊事件)
2、Native -> 邏輯層 (點(diǎn)擊事件)
3、邏輯層 -> Native (setData)
4、Native -> 渲染層 (setData)
以上,是對(duì)兩個(gè)線程之間的通信的一些簡單補(bǔ)充。

總結(jié):

??????以上,我們主要簡單地分析了一下小程序的架構(gòu)實(shí)現(xiàn)呢。小程序是由兩個(gè) webview 線程組成的,視圖層和邏輯層。這種架構(gòu)設(shè)計(jì)從本質(zhì)上來講依舊依賴于 webview,但是雙線程的管理模式加速了首屏渲染模式,避免了單線程下,js 的運(yùn)行阻塞頁面的加載和渲染。關(guān)于小程序架構(gòu)設(shè)計(jì)的內(nèi)容,還有很多需要去剖析了解,包括架構(gòu)設(shè)計(jì)的優(yōu)缺點(diǎn),架構(gòu)設(shè)計(jì)還有哪些地方的可以優(yōu)化的等等。這些需要我們一起繼續(xù)探索。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容