淺析小程式運作機制
寫作背景
接觸小程式有一段時間了,總得來說小程式開發門檻比較低,但其中基本的運作機制和原理還是要懂的。 “例如我在面試的時候問到一個關於小程序的問題,問小程式有window對象嗎?他說有吧”,但其實是沒有的。感覺他並沒有了解小程式底層的一些東西,歸根究底來說應該只能算會使用這個工具,但卻不明白其中的道理。
小程式與一般網頁開發是有很大差別的,這就要從它的技術架構底層去剖析了。還有例如習慣Vue,react開發的開發者會吐槽小程式新建頁面的繁瑣,page必須由多個檔案組成、元件化支援不完善、每次變更data 裡的資料都得setData、沒有像Vue方便的watch監聽、不能操作Dom,對於複雜性場景不太好,之前不支援npm,不支援sass,less預編譯處理語言。
“有的人說小程式就像被閹割的Vue”,哈哈當然了,他們從設計的出發點就不同,咱也得理解小程式設計的初衷,透過它的使用場景,它為什麼採用這種技術架構,這種技術架構有什麼好處,相信在你了解這些之後,就會理解了。下面我會從以下幾個角度去分析小程式的運作機制和它的整體技術架構。
了解小程式的由來
在小程式沒有出來之前,最初微信WebView逐漸成為行動web重要入口,微信發布了一整套網頁開發工具包,稱之為JS-SDK,為所有的Web 開發者打開了一扇全新的窗戶,讓所有開發者都可以使用到微信的原生能力,去完成一些之前做不到或難以做到的事情。
但JS-SDK 的模式並沒有解決使用行動網頁遇到的體驗不良的問題,例如受限於裝置效能和網路速度,會出現白螢幕的可能。因此又設計了一個增強版JS-SDK,也就是“微信 Web 資源離線存儲”,但在復雜的頁面上依然會出現白屏的問題,原因表現在頁面切換的生硬和點擊的遲滯感。這時候需要一個 JS-SDK 所處理不了的,使用戶體驗更好的一個系統,小程式應運而生。
快速的載入
更強大的能力
原生的體驗
易用且安全的微信資料開放
#有效率和簡單的開發
小程式與普通網頁開發的區別
小程式的開發同普通的網頁開發相比有很大的相似性,小程式的主要開發語言也是JavaScript,但二者還是有些差異的。
普通網頁開發可以使用各種瀏覽器提供的DOM API,進行DOM 操作,小程式的邏輯層和渲染層是分開的,邏輯層運行在JSCore 中,並沒有一個完整瀏覽器對象,因而缺少相關的DOM API和BOM API。
普通網頁開發渲染執行緒和腳本執行緒是互斥的,這也是為什麼長時間的腳本運行可能會導致頁面失去回應,而在小程式中,二者是分開的,分別運行在不同的線程中。
網頁開發者在開發網頁的時候,只需要使用到瀏覽器,並且搭配上一些輔助工具或編輯器即可。小程式的開發則有所不同,需要經過申請小程式帳號、安裝小程式開發者工具、設定專案等等流程方可完成。
小程式的執行環境
小程式架構
一、技術選型
一般來說,渲染介面的技術有三種:
用純客戶端原生技術來渲染
用純Web 技術來渲染
用客戶端原生技術與Web 技術結合的混合技術(簡稱Hybrid 技術)來渲染
透過以下幾個面向分析,小程式採用哪種技術方案
開發門檻:Web 門檻低,Native 也有像RN 這樣的框架支援
體驗:Native 體驗比Web 好太多,Hybrid 在某種程度上比Web 接近原生體驗
版本更新:Web 支援線上更新,Native 則需要打包到微信一起審核發布
管控和安全:Web 可跳轉或是改變頁面內容,存在一些不可控因素和安全風險
由於小程式的宿主環境是微信,如果用純客戶端原生技術來寫小程序,那麼小程式碼每次都需要與微信程式碼一起發版,這種方式肯定是不行的。
所以需要像web技術一樣,有一份隨時可更新的資源包放在雲端,透過下載到本地,動態執行後即可渲染出介面。如果用純web技術來渲染小程序,在一些複雜的交互上可能會面臨一些效能問題,這是因為在web技術中,UI渲染跟JavaScript的腳本執行都在一個單線程中執行,這就容易導致有些邏輯任務搶佔UI渲染的資源。
所以最終採用了兩者結合起來的Hybrid 技術來渲染小程序,可以用一種近似web的方式來開發,並且可以實現在線更新代碼,同時引入組件也有以下好處:
擴充 Web 的能力。例如像輸入框元件(input, textarea)有更好地控制鍵盤的能力
體驗更好,同時也減輕WebView 的渲染工作
繞過setData、資料通訊和重渲染流程,讓渲染效能更好
用客戶端原生渲染內建一些複雜元件,可以提供更好的效能
二、雙執行緒模型
#小程式的渲染層和邏輯層分別由2 個執行緒管理:視圖層的介面使用了WebView 進行渲染,邏輯層採用JsCore 執行緒執行JS腳本。
那麼為什麼要這樣設計呢,前面也提到了管控和安全,為了解決這些問題,我們需要阻止開發者使用一些,例如瀏覽器的window對象,跳轉頁面、操作DOM、動態執行腳本的開放性介面。
我們可以使用客戶端系統的 JavaScript 引擎,iOS 下的 JavaScriptCore 框架,安卓下騰訊 x5 核心提供的 JsCore 環境。
這個沙箱環境只提供純 JavaScript 的解釋執行環境,沒有任何瀏覽器相關介面。
這就是小程式雙執行緒模型的由來:
邏輯層:建立一個單獨的執行緒去執行JavaScript,這裡執行的都是有關小程式業務邏輯的程式碼,負責邏輯處理、資料請求、介面呼叫等
視圖層:介面渲染相關的任務全都在WebView 執行緒執行,透過邏輯層程式碼去控制渲染哪些介面。一個小程式存在多個介面,所以視圖層存在多個WebView 執行緒
JSBridge 起到架起上層開發與Native(系統層)的橋樑,使得小程式可透過API使用原生的功能,且部分元件為原生元件實現,從而有良好體驗
三、雙執行緒通訊
把開發者的JS 邏輯程式碼放到單獨的執行緒去運行,但在Webview 執行緒裡,開發者就沒辦法直接操作DOM。
那要怎麼去實作動態變更介面呢?
如上圖所示,邏輯層和試圖層的通訊會由 Native (微信客戶端)做中轉,邏輯層發送網路請求也經由 Native 轉送。
這也就是說,我們可以把 DOM 的更新透過簡單的資料通訊來實現。
Virtual DOM 相信大家都已有了解,大概是這麼過程:用JS 物件模擬DOM 樹-> 比較兩棵虛擬DOM 樹的差異-> 把差異應用到真正的DOM 樹上。
如圖所示:
在渲染層把 WXML 轉換成對應的 JS 物件。
在邏輯層發生資料變更的時候,透過宿主環境提供的 setData 方法把資料從邏輯層傳遞到 Native,然後再轉送到渲染層。
經過對比前後差異,把差異應用在原來的 DOM 樹上,更新介面。
我們透過把 WXML 轉換為數據,透過 Native 進行轉發,來實現邏輯層和渲染層的互動和通訊。
而這樣一個完整的框架,離不開小程式的基礎函式庫。
四、小程式的基礎函式庫
小程式的基礎函式庫可以被注入到視圖層和邏輯層運行,主要用於以下幾個方面:
在視圖層,提供各類元件來組成介面的元素
在邏輯層,提供各類API 來處理各種邏輯
處理資料綁定、元件系統、事件系統、通訊系統等一系列框架邏輯
由於小程式的渲染層和邏輯層是兩個執行緒管理,兩個執行緒各自註入了基礎函式庫。
小程式的基礎函式庫不會被打包在某個小程式的程式碼包裡邊,它會被事先內建在微信客戶端。
這樣可以:
降低業務小程式的程式碼包大小
可以單獨修復基礎庫中的Bug,而無需修改到業務小程式的程式碼包
五、Exparser 框架
Exparser是微信小程式的元件組織框架,內建在小程式基礎庫中,為小程式的各種元件提供基礎的支援。小程式內的所有元件,包括內建元件和自訂元件,都由Exparser組織管理。
Exparser的主要特點包括以下幾點:
基於Shadow DOM模型:模型上與WebComponents的ShadowDOM高度相似,但不依賴瀏覽器的原生支持,也沒有其他依賴函式庫;實作時,也針對性地增加了其他API以支援小程式元件程式設計。
可在純JS環境中運作:這表示邏輯層也具有一定的元件樹組織能力。
高效輕量:效能表現好,在元件實例極多的環境下表現尤其優異,同時程式碼尺寸也較小。
小程式中,所有節點樹相關的操作都依賴Exparser,包括WXML到頁面最終節點樹的建置、createSelectorQuery呼叫和自訂元件特性等。
內建元件
基於Exparser框架,小程式內建了一套元件,提供了視圖容器類別、表單類別、導航類別、媒體類別、開放類別等幾十種組件。有了這麼豐富的組件,再配合WXSS,可以搭建任何效果的介面。在功能層面上,也滿足絕大部分需求。
六、運行機制
小程式啟動會有兩種情況,一種是「冷啟動」,一種是「熱啟動」。假如用戶已經打開過某小程序,然後在一定時間內再次打開該小程序,此時無需重新啟動,只需將後台狀態的小程序切換到前台,這個過程就是熱啟動;冷啟動指的是用戶首次開啟或小程式被微信主動銷毀後再次開啟的情況,此時小程式需要重新載入啟動。
小程式沒有重新啟動的概念
當小程式進入後台,客戶端會維持一段時間的運作狀態,超過一定時間後(目前是5分鐘)會被微信主動銷毀
當短時間內(5s)連續收到兩次以上收到系統記憶體告警,會進行小程式的銷毀
七、更新機制
小程式冷啟動時如果發現有新版本,將會異步下載新版本的程式碼包,並同時用客戶端本地的包進行啟動,即新版本的小程式需要等下一次冷啟動才會應用上。如果需要馬上套用最新版本,可以使用 wx.getUpdateManager API 來處理。
八、效能最佳化
主要的最佳化策略可以歸納為三點:
精簡程式碼,降低WXML結構和JS程式碼的複雜性;
合理使用setData調用,減少setData次數和資料量;
必要時使用分包優化。
1、setData 工作原理
小程式的視圖層目前使用 WebView 作為渲染載體,而邏輯層則是由獨立的 JavascriptCore 作為運作環境。在架構上,WebView 和 JavascriptCore 都是獨立的模組,並不具備資料直接共享的通道。目前,視圖層和邏輯層的資料傳輸,實際上透過兩邊提供的 evaluateJavascript 所實現。也就是使用者傳輸的數據,需要將其轉換為字串形式傳遞,同時把轉換後的數據內容拼接成一份 JS 腳本,再透過執行 JS 腳本的形式傳遞到兩邊獨立環境。
而 evaluateJavascript 的執行會受很多方面的影響,資料到達視圖層並不是即時的。
2、常見的setData 操作錯誤
頻繁的去setData在我們分析過的一些案例裡,部分小程式會非常頻繁(毫秒級)的去setData,其導致了兩個後果:Android下用戶在滑動時會感覺到卡頓,操作反饋延遲嚴重,因為JS 線程一直在編譯執行渲染,未能及時將用戶操作事件傳遞到邏輯層,邏輯層亦無法及時將操作處理結果及時傳遞到視圖層;渲染有出現延遲,由於WebView 的JS 執行緒一直處於忙碌狀態,邏輯層到頁面層的通訊耗時上升,視圖層收到的資料訊息時距離發出時間已經過了幾百毫秒,渲染的結果並不實時;
每次setData 都傳遞大量新資料由setData的底層實作可知,我們的資料傳輸實際上是一次evaluateJavascript
#腳本過程,當資料量過大時會增加腳本的編譯執行時間,佔用WebView JS 線程, 後台態頁面進行setData當頁面進入後台態(用戶不可見),不應該繼續去進行setData,後台態頁面的渲染用戶是無法感受的,另外後台態頁面去setData也會搶佔前台頁面的執行。
總結
大致上從以上幾個角度分析了小程式的底層架構,從小程式的由來、到雙執行緒的出現、設計、通訊、到基礎函式庫、Exparser 框架、再到運作機制、效能最佳化等等,都是一個相關而又相互影響的選擇。關於小程式的底層框架設計,應該還有很多,每個框架的誕生都有其意義,我們身為開發者能做的不只是會使用這個工具,還應該理解它的設計模式。這樣才不會被工具左右,才能走的更遠!
以上是淺析小程式運作機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

隨著行動互聯網技術和智慧型手機的普及,微信成為了人們生活中不可或缺的一個應用。而微信小程式則讓人們可以在不需要下載安裝應用程式的情況下,直接使用小程式來解決一些簡單的需求。本文將介紹如何使用Python來開發微信小程式。一、準備工作在使用Python開發微信小程式之前,需要先安裝相關的Python函式庫。這裡推薦使用wxpy和itchat這兩個函式庫。 wxpy是一個微信機器

小程式能用react,其使用方法:1、基於「react-reconciler」實作一個渲染器,產生一個DSL;2、建立一個小程式元件,去解析和渲染DSL;3、安裝npm,並執行開發者工具中的建構npm;4、在自己的頁面中引入包,再利用api即可完成開發。

實作微信小程式中的卡片翻轉特效在微信小程式中,實現卡片翻轉特效是一種常見的動畫效果,可以提升使用者體驗和介面互動的吸引力。以下將具體介紹如何在微信小程式中實現卡片翻轉的特效,並提供相關程式碼範例。首先,需要在小程式的頁面佈局檔案中定義兩個卡片元素,一個用於顯示正面內容,一個用於顯示背面內容,具體範例程式碼如下:<!--index.wxml-->&l

本站10月31日消息,今年5月27日,螞蟻集團宣布啟動“漢字拾光計劃”,最近又迎來新進展:支付寶上線“漢字拾光-生僻字”小程序,用於向社會徵集生僻字,補充生僻字庫,同時提供不同的生僻字輸入體驗,以幫助完善支付寶內的生僻字輸入方法。目前,用戶搜尋「漢字拾光」、「生僻字」等關鍵字就可以進入「生僻字」小程式。在小程式裡,使用者可以提交尚未被系統辨識輸入的生僻字圖片,支付寶工程師確認後,將會對字庫進行補錄入。本站注意到,使用者也可以在小程式體驗最新的拆字輸入法,這項輸入法針對讀音不明確的生僻字設計。用戶拆

uniapp如何實現小程式和H5的快速轉換,需要具體程式碼範例近年來,隨著行動網路的發展和智慧型手機的普及,小程式和H5成為了不可或缺的應用形式。而uniapp作為一個跨平台的開發框架,可以在一套程式碼的基礎上,快速實現小程式和H5的轉換,大大提高了開發效率。本文將介紹uniapp如何實現小程式和H5的快速轉換,並給出具體的程式碼範例。一、uniapp簡介unia

小程序備案操作步驟:1、準備個人身分證影本、企業營業執照影本、法人身分證影本等備案資料;2、登入小程式管理後台;3、進入小程式設定頁;4、選擇“基本設定」;5、填寫備案資料;6、上傳備案資料;7、提交備案申請;8、等待審核結果,如果備案不透過要根據原因進行修改,並重新提交備案申請;9、備案後續操作即可。

實現思路x01服務端的建立首先,在服務端,使用socket進行訊息的接受,每接受一個socket的請求,就開啟一個新的線程來管理訊息的分發與接受,同時,又存在一個handler來管理所有的線程,從而實現對聊天室的各種功能的處理x02客戶端的建立客戶端的建立就要比服務端簡單多了,客戶端的作用只是對消息的發送以及接受,以及按照特定的規則去輸入特定的字符從而實現不同的功能的使用,因此,在客戶端這裡,只需要去使用兩個線程,一個是專門用於接受消息,一個是專門用於發送消息的至於為什麼不用一個呢,那是因為,只

1.開啟微信小程序,進入對應的小程式頁面。 2.在小程式頁面中尋找會員相關入口,通常會員入口在底部導覽列或個人中心等位置。 3.點選會員入口,進入會員申請頁。 4、在會員申請頁面,填寫相關信息,如手機號碼、姓名等,完成資料填寫後,提交申請。 5.小程式方會對會員申請審核,審核通過後,用戶即可成為微信小程式會員。 6.作為會員,用戶將享有更多的會員權益,如積分、優惠券、會員專屬活動等
