小程序框架原理之渲染流程及通訊流程

MINA

MINA 是在微信中開發小程序的框架。其目標是經過儘量簡單、高效的方式讓開發者能夠在微信中開發具備原生 APP 體驗的服務。html

MINA 提供了本身的視圖層描述語言 WXMLWXSS,以及基於 JavaScript 的邏輯層框架,核心是一個響應的數據綁定系統。整個系統分爲視圖層(View)和邏輯層(App Service),並在視圖層與邏輯層間提供了數據傳輸和事件系統,可讓開發者能夠方便的聚焦於數據與邏輯上。web

MINA 讓數據與視圖保持同步很是簡單。當作數據修改的時候,只須要在邏輯層修改數據,視圖層就會作相應的更新。MINA 是騰訊給微信小程序命名的框架,實際上應用的是目前業界最著名的 MVVM 模式。算法

wxml的真實面目

咱們都知道小程序提供了不少方便快捷的自定義組件(標籤),但你知道小程序的這些組件編譯事後會渲染成什麼嗎?先說答案,其實 wxml 通過編譯後會渲染成 html 。很簡單的一點,你發如今小程序內編寫 html 標籤,最終也能夠運行。小程序

探尋

光說可能體會不到,下面開始探尋小程序真實渲染的樣子。先看下開發者工具內 wxml 的內容,待會和真實渲染的內容作對比。微信小程序

接下來一步步找到小程序 wxml 渲染完成的真實樣子,工具菜單欄點擊微信開發者工具,選擇調試微信開發者工具。打開的控制檯能夠調試整個微信開發者工具,用調試箭頭指向小程序內容區域,這時能夠看到小程序視圖層是被嵌套在 webviewiframe 內。微信

可是當咱們點開 iframe 是沒法查看到裏面內容的。若是想要查看調試 webview,只需選中 webview 打開它的調試工具便可,在控制檯輸入如下代碼:微信開發

$$('webview')[0].showDevTools(true)

能夠看到又打開了一個調試窗口,這裏面就是小程序視圖層渲染的真實樣子:框架

能夠看到結構和 wxml 裏的內容幾乎如出一轍,只是 topbar 變成了 wx-topbarview 變成了 wx-view等。這些都是內部實現的一套對應小程序標籤的 webComponent 組件,而 webComponent 實際渲染出來仍是 html 標籤。dom

轉換過程

轉換過程是微信開發者工具內部經過一個可執行編譯工具實現對小程序文件轉換。在微信開發者工具控制檯輸入 openVendor() 會打開一個文件夾,裏面存放着微信的基礎庫及工具,在裏面能夠找到 wcc.exewcsc.exe 執行文件,分別對應 wxmlwxss 的文件轉換。xss

該工具能夠單獨對小程序文件進行轉換,使用方法 ./wcc -d wxml文件路徑 >> 輸出路徑。例如,將工具複製到一個文件夾內,再將一個 wxml 放入該文件夾內,命令行輸入 :

./wcc -d index.wxml >> index.js

可能有人很好奇爲何是生成 js 文件,而不是 html 文件。緣由很簡單,由於須要處理 wxml 的動態綁定數據。看看這個 js 文件生成的是什麼:

由於這些都是混淆壓縮過的代碼,基本沒有可讀性。這裏只須要注意一個函數就好,那就是 $gwx。這是個很關鍵的函數,它的做用是生成虛擬dom樹,用於渲染真實節點。

接下來回到 webview 調試窗口,在 head 內找到這段插入的 script 標籤代碼:

有沒有很熟悉,沒錯,就是和上面轉換後的代碼是同一個東西。也就是說,咱們的 wxml 文件經過編譯,最終在視圖層中執行的就是這段 js 代碼(這裏只是能夠大概這麼理解,實際須要向邏輯層獲取數據才能渲染頁面)。控制檯輸入 $gwx 發現這個函數存在,那麼這個函數如何生成虛擬dom呢?$gwx 函數的第一個參數接收一個路徑參數,這個路徑就是 wxml 文件路徑,此時在控制檯輸入:

let generateFunc = $gwx('./pages/index/index.wxml')
generateFunc()

這時頁面虛擬dom就生成出來了:

單純調用 generateFunc 生成出來的虛擬dom是沒有動態綁定數據的,若是想要動態的綁定數據,在調用 generateFunc 時傳入一個數據對象。可是數據全在邏輯層裏,這時就須要進行通訊了。

數據通訊

首先要知道小程序時運行在基礎庫之上的,但它們都是壓縮打包好的,後面找到反編譯出來的基礎庫代碼,其中最重要的就是 WAService.jsWAWebview.js,它們分別是視圖層和邏輯層的核心實現。

它們之間須要一個橋樑來進行通訊,那就是 JS BridgeJS Bridge 提供調用原生功能的接口(攝像頭,定位等),它的核心是構建原生和非原生間消息通訊的通道,並且這個通訊的通道是雙向的。經過 JS Bridge 的發佈訂閱方法,視圖層和邏輯層進行數據通訊。

通訊流程

接下來看看視圖層和邏輯層的交互流程:

  1. wxml 轉換成對應的 js 文件,等待生成虛擬dom函數 $gwx 準備完成,使用 dispatchEvent 通知 WAWebview
  1. WAWebview 監聽到 generateFuncReady 事件觸發,使用 WeixinJSBridge.publish 向邏輯層通訊。
  1. 邏輯層處理邏輯,也就是咱們日常寫的小程序 js 文件裏的東西,而後經過 JS Bridge 通知並返回數據給視圖層。

  2. 視圖層接收到數據,將數據傳入生成虛擬dom的函數內,渲染頁面,固然小程序也有相應的diff算法。

例如在 wxml 中綁定一個動態數據 title,視圖層接收到數據後,從新生成虛擬dom

generateFunc({
  title'標題'
})
  1. 初始化完成後,就會走對應的其餘生命週期,或者用戶觸發事件,數據都會在邏輯層處理完成後經過 JS Bridge 通知到視圖層,視圖層再次調用生成虛擬dom的函數,更新頁面。

wxss如何工做

wxss 工做原理和 wxml 差很少,都是經過工具轉換爲 js。爲何又是轉換成 js,由於有 rpx 單位,須要根據手機尺寸進行設置 px

wcsc.exe 轉換命令以下:

./wcsc -js index.wxss >> index.js

能夠看到文件開頭就是對 rpx 的轉換

以後建立 style 標籤,動態添加到視圖層中

最後

附上 WAService.jsWAWebview.js 的代碼做爲學習參考。

相關文章
相關標籤/搜索