微信小程序底層架構

1. 與h5頁面的區別

從技術的發展角度來看,微信小程序是從微信中的 webViewJS-SDK 進化到了今天的形態。那麼,小程序和普通的h5頁面到底有什麼區別呢?前端

  • 運行環境:小程序基於瀏覽器內核重構的內置解析器,而 h5 的宿主環境是瀏覽器。因此小程序中沒有 DOMBOM 的相關 APIjQuery和一些 NPM 包都不能在小程序中使用;
  • 系統權限:小程序能得到更多的系統權限,如網絡通訊狀態、數據緩存能力等;
  • 渲染機制:小程序的邏輯層和渲染層是分開的,而 h5 頁面 UI 渲染跟 JavaScript 的腳本執行都在一個單線程中,互斥。因此 h5 頁面中長時間的腳本運行可能會致使頁面失去響應。

其實,小程序開發過程當中咱們面對的是 iOSAndroid 微信客戶端和輔助開發的小程序開發者工具。根據官方文檔,這三大運行環境也是有所區別的:web

運行環境 邏輯層 渲染層
iOS JavaScriptCore WKWebView
Android X5 JSCore X5瀏覽器
小程序開發者工具 NWJS Chrome WebView

因此微信小程序介於 web 端和原生 App 之間,可以豐富調用功能接口,同時又跨平臺。小程序

2. 小程序架構

2.1 雙線程模型

小程序的渲染層和邏輯層分別由2個線程管理:微信小程序

  • 渲染層:界面渲染相關的任務全都在 WebView 線程裏執行。一個小程序存在多個界面,因此渲染層存在多個 WebView線程。
  • 邏輯層:採用 JsCore 線程運行JS腳本。

視圖層和邏輯層經過系統層的 WeixinJsBridage 進行通訊:邏輯層把數據變化通知到視圖層,觸發視圖層頁面更新,視圖層把觸發的事件通知到邏輯層進行業務處理。瀏覽器

(頁面渲染的具體流程是:在渲染層,宿主環境會把 WXML 轉化成對應的 JS 對象,在邏輯層發生數據變動的時候,咱們須要經過宿主環境提供的 setData 方法把數據從邏輯層傳遞到渲染層,再通過對比先後差別,把差別應用在原來的Dom樹上,渲染出正確的UI界面)緩存

雙線程模型

雙線程模型是小程序框架與業界大多數前端 Web 框架不一樣之處。基於這個模型,能夠更好地管控以及提供更安全的環境。缺點是帶來了無處不在的異步問題(任何數據傳遞都是線程間的通訊,也就是都會有必定的延時),不太小程序在框架層面已經封裝好了異步帶來的時序問題。安全

2.2 組件系統

咱們知道小程序是有本身的組件的,這些基本組件就是基於 Exparser 框架。 Exparser 基於 WebComponentsShadowDOM 模型,可是不依賴瀏覽器的原生支持,並且可在 純 JS 環境中運行。bash

小程序中,全部節點樹相關的操做都依賴於 Exparser,包括 WXML 到頁面最終節點樹的構建、CreateSelectorQuery 調用和自定義組件特性等。微信

如今微信小程序也支持自定義組件了,用法和組件間通訊相似於 Vue網絡

2.3 原生組件

在內置組件中,有一些組件並不徹底在 Exparser 的渲染體系下,而是由客戶端原生參與組件的渲染。好比說 Map 組件。它渲染的層級比在 WebView 層渲染的普通組件要高。

引入原生組件的優勢是:

  • 擴展 Web 的能力
  • 體驗更好,減輕 WebView 的渲染工做
  • 繞過 setData、數據通訊和重渲染流程,性能更好

2.4 運行機制

2.4.1 啓動

  • 熱啓動::假如用戶已經打開過某小程序,而後在必定時間內再次打開該小程序,此時無需從新啓動,只需將後臺態的小程序切換到前臺,這個過程就是熱啓動;
  • 冷啓動:用戶首次打開或小程序被微信主動銷燬後再次打開的狀況,此時小程序須要從新加載啓動,即冷啓動。

運行機制

2.4.2 銷燬

只有當小程序進入後臺必定時間,或者系統資源佔用太高,纔會被真正的銷燬。

2.5 更新機制

開發者在後臺發佈新版本以後,沒法馬上影響到全部現網用戶,但最差狀況下,也在發佈以後 24 小時以內下發新版本信息到用戶。

小程序每次冷啓動時,都會檢查是否有更新版本,若是發現有新版本,將會異步下載新版本的代碼包,並同時用客戶端本地的包進行啓動,即新版本的小程序須要等下一次冷啓動纔會應用上。

因此若是想讓用戶使用最新版本的小程序,能夠利用 wx.getUpdateManager 作個檢查更新的功能:

checkNewVersion() {
    const updateManager = wx.getUpdateManager();
    updateManager.onCheckForUpdate((res) => {
      console.log('hasUpdate', res.hasUpdate);
      // 請求完新版本信息的回調
      if (res.hasUpdate) {
        updateManager.onUpdateReady(() => {
          this.setData({
            hasNewVersion: true
          });
        });
      }
    });
  }
複製代碼

微信小程序的基礎底層架構大概就這麼多,有機會再看看源碼思考解析吧。

相關文章
相關標籤/搜索