小程序底層架構

小程序底層架構

與瀏覽器對比

以微信小程序爲例,與瀏覽器中的對應關係:

  • js 開發邏輯代碼 -> js -> v8
  • wxss (多了rpx單位)控制樣式 -> css -> 瀏覽器渲染器
  • wxml xml語言 控制渲染層展示 -> html -> 瀏覽器渲染器 -> dom

瀏覽器

  • 單線程 存在阻塞

小程序

  • 雙線程架構
    • js 邏輯層
    • wxml、wxss 視圖層
  • JSBridge 通信(可以實現相機、掃碼)

在這裏插入圖片描述

微信小程序初級架構

  • 所有的邏輯代碼會打成一份,一個小程序只有一個邏輯層,包含所有頁面邏輯 js
  • 視圖層(渲染層)一個頁面對應一個 Webview,小程序中頁面棧最多十層。
    • webview 用來渲染 wxml 和 wxss
      • 在本地開發工具,直接用 iframe
      • 在客戶端,用真的 webview

在這裏插入圖片描述

小程序運行環境

運行環境 邏輯層 渲染層
iOS JavaScriptCore WKWebView
安卓 V8 chromium定製內核
小程序開發者工具 NWJS Chrome WebView

nw:node(io/網絡/資源處理/js)-webkit(html/css)

底層實現(基礎庫)

基礎庫:對底層運行時的封裝,提供事件、數據變更、通信、基礎函數

底層需要實現的功能:

  1. 視圖層和邏輯層的編譯
  2. 邏輯層和視圖層之間的通信

查看基礎庫

微信開發工具 -> 執行 openVendor() -> 打開基礎庫

可以看到兩個可執行文件:

  • wcc: Wechat WXML Complier wxml 編譯器
  • wcsc: Wechat WXSS Compiler wxss 編譯器

和基礎庫 xxx.wxvpkg

基礎庫內容

基礎庫用 wxappUnpacker 反編譯,得到:

  1. WAWebview.js 視圖層引擎
  • Foundation 基礎模塊
    • 提供環境變量 env、isService、isWebview、eventEmit、jsbridge、ready監聽 配置
  • WeixinJSBridge 消息通信機制
  • NativeBuffer 轉換數據格式
  • Reporter 日誌系統
  • exparser 組件系統 Shadow DOM、WebComponent 規範、wx-element
    • 提供友好交互的組件 picker、slider、swiper 等
    • 承接原生組件 video、canvas 等
    • 事件系統
    • 註冊組件 window.exparser.registerElement()
  • __virtualDOM__
  1. WAService.js 邏輯層引擎
  • Foundation 基礎模塊
    • 提供環境變量 env、isService、isWebview、eventEmit、jsbridge、ready監聽 配置
  • WeixinJSBridge 消息通信機制
  • 路由管理
  • 生命週期管理
  • __subContextEngine: App、Page、Component getApp
  • __virtualDOM__:提供 querySelector 方法

編譯器

編譯 wxml

wcc(Wechat WXML Complier) wxml 編譯器 -> js
初始化時:

  1. 編譯生成 js,執行 js 生成構建虛擬 dom 的函數
  2. 數據傳遞給 構建虛擬 dom 的函數,生成 vdom 描述
  3. vdom 描述經過組件系統 exparser 的解析構建真實 dom

數據變更時:

  1. 執行上面 2、3 步
  2. dom diff 對比、渲染

wxml 經過 WAWebview 編譯成 js,js + 虛擬 dom -> wxml描述文件,交給組件系統 exparser,去渲染更新

編譯 wxss

wcsc(Wechat WXSS Compiler) wxss 編譯器 -> js

  1. 處理單位 rpx,根據手機物理像素及分辨率來計算實際應該爲多少
  2. 生成新的 style,插入

初始化流程

渲染層

控制檯輸入 document.getElementsByTag('webview')[0] 得到渲染層。

  1. 初始化 __webviewId__(標識當前是哪個 webview )、__wxAppCode__
  2. wcc 生成渲染器方法的代碼(wxml -> js)
  3. 加載執行 wcsc 打包出來的代碼(js代碼),生成 css
  4. 初始化頁面配置
  5. $gwx -> generateFunc(渲染器,執行生成虛擬 Dom),需要數據
  6. 觸發自定義事件,傳遞渲染器函數
     var generateFunc = $gwx(decodeName)
     if(generateFunc) {
         
         
       var CE = window.CustomEvent
       document.dispatchEvent(new CE('generateFuncReady', {
         
         
         detail: {
         
         
           generateFunc: generateFunc
         }
       }))
     } else {
         
         
       ...
     }
    
  7. 基礎庫 WAWebview 中監聽了 generateFuncReady 事件,該事件中會觸發 WexinJSBridge,通知邏輯層渲染層已加載完成,等待邏輯層傳數據。邏輯層執行完之後執行 generateFunc 回調,並拿到邏輯層傳來的數據,生成虛擬 dom
  8. 虛擬 dom 描述經過組件系統 exparser 的解析構建真實 dom

邏輯層

控制檯輸入 document 得到邏輯層。

  1. 初始化配置項(頁面配置項、全局配置項)
  2. 加載邏輯層基礎庫(維護了 Page、App、Component、wx.getSetting、wx.scanCode 等)
  3. 維護一個邏輯層渲染器,加載邏輯代碼(開發者寫的代碼)
  4. 構建 __wxAppCode__,保存所有頁面的配置和渲染器方法

整體流程圖

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章