潮基鄉(xiāng)淺析小程序運(yùn)行機(jī)制
閱讀 20961 · 發(fā)布日期 2020-08-24 17:26 · 溫州優(yōu)光網(wǎng)絡(luò)科技有限公司|建站|APP小程序制作|做網(wǎng)站SEO推廣優(yōu)化
【摘要】
寫作背景接觸小程序有一段時(shí)間了,總得來說小程序開發(fā)門檻比較低,但其中基本的運(yùn)行機(jī)制和原理還是要懂的?!氨热缥以诿嬖嚨臅r(shí)候問到一個(gè)關(guān)于小程序的問題,問小程序有window對(duì)象嗎?他說有吧”,但其實(shí)是沒有的。感覺他并沒有了解小程序底層的一些東西,歸根結(jié)底來說應(yīng)該只能算會(huì)使用這個(gè)工具,但并不明白其中的道理。小程序與普通網(wǎng)頁開... 【溫州小程序開發(fā),溫州微信公眾號(hào),平陽做網(wǎng)站,平陽網(wǎng)站建設(shè)公司,平陽小程序商城制作,昆陽萬全做網(wǎng)站,鰲江水頭小程序,蕭江騰蛟微信公眾號(hào),山門順溪南雁海西南麂鳳臥麻步懷溪網(wǎng)絡(luò)網(wǎng)店服務(wù),政采云網(wǎng)店管理服務(wù)】...
寫作背景接觸小程序有一段時(shí)間了,總得來說小程序開發(fā)門檻比較低,但其中基本的運(yùn)行機(jī)制和原理還是要懂的。
“比如我在面試的時(shí)候問到一個(gè)關(guān)于小程序的問題,問小程序有window對(duì)象嗎?他說有吧”,但其實(shí)是沒有的。
感覺他并沒有了解小程序底層的一些東西,歸根結(jié)底來說應(yīng)該只能算會(huì)使用這個(gè)工具,但并不明白其中的道理。
小程序與普通網(wǎng)頁開發(fā)是有很大差別的,這就要從它的技術(shù)架構(gòu)底層去剖析了。
還有比如習(xí)慣Vue,react開發(fā)的開發(fā)者會(huì)吐槽小程序新建頁面的繁瑣,page必須由多個(gè)文件組成、組件化支持不完善、每次更改 data 里的數(shù)據(jù)都得setData、沒有像Vue方便的watch監(jiān)聽、不能操作Dom,對(duì)于復(fù)雜性場(chǎng)景不太好,之前不支持npm,不支持sass,less預(yù)編譯處理語言。
“有的人說小程序就像被閹割的Vue”,哈哈當(dāng)然了,他們從設(shè)計(jì)的出發(fā)點(diǎn)就不同,咱也得理解小程序設(shè)計(jì)的初衷,通過它的使用場(chǎng)景,它為什么采用這種技術(shù)架構(gòu),這種技術(shù)架構(gòu)有什么好處,相信在你了解完這些之后,就會(huì)理解了。
下面我會(huì)從以下幾個(gè)角度去分析小程序的運(yùn)行機(jī)制和它的整體技術(shù)架構(gòu)。
了解小程序的由來在小程序沒有出來之前,最初微信WebView逐漸成為移動(dòng)web重要入口,微信發(fā)布了一整套網(wǎng)頁開發(fā)工具包,稱之為 JS-SDK,給所有的 Web 開發(fā)者打開了一扇全新的窗戶,讓所有開發(fā)者都可以使用到微信的原生能力,去完成一些之前做不到或者難以做到的事情。
但JS-SDK 的模式并沒有解決使用移動(dòng)網(wǎng)頁遇到的體驗(yàn)不良的問題,比如受限于設(shè)備性能和網(wǎng)絡(luò)速度,會(huì)出現(xiàn)白屏的可能。
因此又設(shè)計(jì)了一個(gè)增強(qiáng)版JS-SDK,也就是“微信 Web 資源離線存儲(chǔ)”,但在復(fù)雜的頁面上依然會(huì)出現(xiàn)白屏的問題,原因表現(xiàn)在頁面切換的生硬和點(diǎn)擊的遲滯感。
這個(gè)時(shí)候需要一個(gè) JS-SDK 所處理不了的,使用戶體驗(yàn)更好的一個(gè)系統(tǒng),小程序應(yīng)運(yùn)而生。
快速的加載更強(qiáng)大的能力原生的體驗(yàn)易用且安全的微信數(shù)據(jù)開放高效和簡(jiǎn)單的開發(fā)小程序與普通網(wǎng)頁開發(fā)的區(qū)別小程序的開發(fā)同普通的網(wǎng)頁開發(fā)相比有很大的相似性,小程序的主要開發(fā)語言也是 JavaScript,但是二者還是有些差別的。
普通網(wǎng)頁開發(fā)可以使用各種瀏覽器提供的 DOM API,進(jìn)行 DOM 操作,小程序的邏輯層和渲染層是分開的,邏輯層運(yùn)行在 JSCore 中,并沒有一個(gè)完整瀏覽器對(duì)象,因而缺少相關(guān)的DOM API和BOM API。
普通網(wǎng)頁開發(fā)渲染線程和腳本線程是互斥的,這也是為什么長(zhǎng)時(shí)間的腳本運(yùn)行可能會(huì)導(dǎo)致頁面失去響應(yīng),而在小程序中,二者是分開的,分別運(yùn)行在不同的線程中。
網(wǎng)頁開發(fā)者在開發(fā)網(wǎng)頁的時(shí)候,只需要使用到瀏覽器,并且搭配上一些輔助工具或者編輯器即可。
小程序的開發(fā)則有所不同,需要經(jīng)過申請(qǐng)小程序帳號(hào)、安裝小程序開發(fā)者工具、配置項(xiàng)目等等過程方可完成。
小程序的執(zhí)行環(huán)境小程序架構(gòu)一、技術(shù)選型一般來說,渲染界面的技術(shù)有三種:
用純客戶端原生技術(shù)來渲染用純 Web 技術(shù)來渲染用客戶端原生技術(shù)與 Web 技術(shù)結(jié)合的混合技術(shù)(簡(jiǎn)稱 Hybrid 技術(shù))來渲染通過以下幾個(gè)方面分析,小程序采用哪種技術(shù)方案開發(fā)門檻:
Web 門檻低,Native 也有像 RN 這樣的框架支持體驗(yàn):
Native 體驗(yàn)比 Web 要好太多,Hybrid 在一定程度上比 Web 接近原生體驗(yàn)版本更新:
Web 支持在線更新,Native 則需要打包到微信一起審核發(fā)布管控和安全:
Web 可跳轉(zhuǎn)或是改變頁面內(nèi)容,存在一些不可控因素和安全風(fēng)險(xiǎn)由于小程序的宿主環(huán)境是微信,如果用純客戶端原生技術(shù)來編寫小程序,那么小程序代碼每次都需要與微信代碼一起發(fā)版,這種方式肯定是不行的。
所以需要像web技術(shù)那樣,有一份隨時(shí)可更新的資源包放在云端,通過下載到本地,動(dòng)態(tài)執(zhí)行后即可渲染出界面。
如果用純web技術(shù)來渲染小程序,在一些復(fù)雜的交互上可能會(huì)面臨一些性能問題,這是因?yàn)樵趙eb技術(shù)中,UI渲染跟JavaScript的腳本執(zhí)行都在一個(gè)單線程中執(zhí)行,這就容易導(dǎo)致一些邏輯任務(wù)搶占UI渲染的資源。
所以最終采用了兩者結(jié)合起來的Hybrid 技術(shù)來渲染小程序,可以用一種近似web的方式來開發(fā),并且可以實(shí)現(xiàn)在線更新代碼,同時(shí)引入組件也有以下好處:
擴(kuò)展 Web 的能力。
比如像輸入框組件(input, textarea)有更好地控制鍵盤的能力體驗(yàn)更好,同時(shí)也減輕 WebView 的渲染工作繞過 setData、數(shù)據(jù)通信和重渲染流程,使渲染性能更好用客戶端原生渲染內(nèi)置一些復(fù)雜組件,可以提供更好的性能二、雙線程模型小程序的渲染層和邏輯層分別由 2 個(gè)線程管理:
視圖層的界面使用了 WebView 進(jìn)行渲染,邏輯層采用 JsCore 線程運(yùn)行 JS腳本。
那么為什么要這樣設(shè)計(jì)呢,前面也提到了管控和安全,為了解決這些問題,我們需要阻止開發(fā)者使用一些,例如瀏覽器的window對(duì)象,跳轉(zhuǎn)頁面、操作DOM、動(dòng)態(tài)執(zhí)行腳本的開放性接口。
我們可以使用客戶端系統(tǒng)的 JavaScript 引擎,iOS 下的 JavaScriptCore 框架,安卓下騰訊 x5 內(nèi)核提供的 JsCore 環(huán)境。
這個(gè)沙箱環(huán)境只提供純 JavaScript 的解釋執(zhí)行環(huán)境,沒有任何瀏覽器相關(guān)接口。
這就是小程序雙線程模型的由來:
邏輯層:
創(chuàng)建一個(gè)單獨(dú)的線程去執(zhí)行 JavaScript,在這里執(zhí)行的都是有關(guān)小程序業(yè)務(wù)邏輯的代碼,負(fù)責(zé)邏輯處理、數(shù)據(jù)請(qǐng)求、接口調(diào)用等視圖層:
界面渲染相關(guān)的任務(wù)全都在 WebView 線程里執(zhí)行,通過邏輯層代碼去控制渲染哪些界面。
一個(gè)小程序存在多個(gè)界面,所以視圖層存在多個(gè) WebView 線程JSBridge 起到架起上層開發(fā)與Native(系統(tǒng)層)的橋梁,使得小程序可通過API使用原生的功能,且部分組件為原生組件實(shí)現(xiàn),從而有良好體驗(yàn)三、雙線程通信把開發(fā)者的 JS 邏輯代碼放到單獨(dú)的線程去運(yùn)行,但在 Webview 線程里,開發(fā)者就沒法直接操作 DOM。
那要怎么去實(shí)現(xiàn)動(dòng)態(tài)更改界面呢?如上圖所示,邏輯層和試圖層的通信會(huì)由 Native (微信客戶端)做中轉(zhuǎn),邏輯層發(fā)送網(wǎng)絡(luò)請(qǐng)求也經(jīng)由 Native 轉(zhuǎn)發(fā)。
這也就是說,我們可以把 DOM 的更新通過簡(jiǎn)單的數(shù)據(jù)通信來實(shí)現(xiàn)。
Virtual DOM 相信大家都已有了解,大概是這么個(gè)過程:
用 JS 對(duì)象模擬 DOM 樹 -> 比較兩棵虛擬 DOM 樹的差異 -> 把差異應(yīng)用到真正的 DOM 樹上。
如圖所示:
在渲染層把 WXML 轉(zhuǎn)化成對(duì)應(yīng)的 JS 對(duì)象。
在邏輯層發(fā)生數(shù)據(jù)變更的時(shí)候,通過宿主環(huán)境提供的 setData 方法把數(shù)據(jù)從邏輯層傳遞到 Native,再轉(zhuǎn)發(fā)到渲染層。
經(jīng)過對(duì)比前后差異,把差異應(yīng)用在原來的 DOM 樹上,更新界面。
我們通過把 WXML 轉(zhuǎn)化為數(shù)據(jù),通過 Native 進(jìn)行轉(zhuǎn)發(fā),來實(shí)現(xiàn)邏輯層和渲染層的交互和通信。
而這樣一個(gè)完整的框架,離不開小程序的基礎(chǔ)庫(kù)。
四、小程序的基礎(chǔ)庫(kù)小程序的基礎(chǔ)庫(kù)可以被注入到視圖層和邏輯層運(yùn)行,主要用于以下幾個(gè)方面:
在視圖層,提供各類組件來組建界面的元素在邏輯層,提供各類 API 來處理各種邏輯處理數(shù)據(jù)綁定、組件系統(tǒng)、事件系統(tǒng)、通信系統(tǒng)等一系列框架邏輯由于小程序的渲染層和邏輯層是兩個(gè)線程管理,兩個(gè)線程各自注入了基礎(chǔ)庫(kù)。
小程序的基礎(chǔ)庫(kù)不會(huì)被打包在某個(gè)小程序的代碼包里邊,它會(huì)被提前內(nèi)置在微信客戶端。
這樣可以:
降低業(yè)務(wù)小程序的代碼包大小可以單獨(dú)修復(fù)基礎(chǔ)庫(kù)中的 Bug,無需修改到業(yè)務(wù)小程序的代碼包五、Exparser 框架Exparser是微信小程序的組件組織框架,內(nèi)置在小程序基礎(chǔ)庫(kù)中,為小程序的各種組件提供基礎(chǔ)的支持。
小程序內(nèi)的所有組件,包括內(nèi)置組件和自定義組件,都由Exparser組織管理。
Exparser的主要特點(diǎn)包括以下幾點(diǎn):
基于Shadow DOM模型:
模型上與WebComponents的ShadowDOM高度相似,但不依賴瀏覽器的原生支持,也沒有其他依賴庫(kù);實(shí)現(xiàn)時(shí),還針對(duì)性地增加了其他API以支持小程序組件編程。
可在純JS環(huán)境中運(yùn)行:
這意味著邏輯層也具有一定的組件樹組織能力。
高效輕量:
性能表現(xiàn)好,在組件實(shí)例極多的環(huán)境下表現(xiàn)尤其優(yōu)異,同時(shí)代碼尺寸也較小。
小程序中,所有節(jié)點(diǎn)樹相關(guān)的操作都依賴于Exparser,包括WXML到頁面最終節(jié)點(diǎn)樹的構(gòu)建、createSelectorQuery調(diào)用和自定義組件特性等。
內(nèi)置組件基于Exparser框架,小程序內(nèi)置了一套組件,提供了視圖容器類、表單類、導(dǎo)航類、媒體類、開放類等幾十種組件。
有了這么豐富的組件,再配合WXSS,可以搭建出任何效果的界面。
在功能層面上,也滿足絕大部分需求。
六、運(yùn)行機(jī)制小程序啟動(dòng)會(huì)有兩種情況,一種是「冷啟動(dòng)」,一種是「熱啟動(dòng)」。
假如用戶已經(jīng)打開過某小程序,然后在一定時(shí)間內(nèi)再次打開該小程序,此時(shí)無需重新啟動(dòng),只需將后臺(tái)狀態(tài)的小程序切換到前臺(tái),這個(gè)過程就是熱啟動(dòng);冷啟動(dòng)指的是用戶首次打開或小程序被微信主動(dòng)銷毀后再次打開的情況,此時(shí)小程序需要重新加載啟動(dòng)。
小程序沒有重啟的概念當(dāng)小程序進(jìn)入后臺(tái),客戶端會(huì)維持一段時(shí)間的運(yùn)行狀態(tài),超過一定時(shí)間后(目前是5分鐘)會(huì)被微信主動(dòng)銷毀當(dāng)短時(shí)間內(nèi)(5s)連續(xù)收到兩次以上收到系統(tǒng)內(nèi)存告警,會(huì)進(jìn)行小程序的銷毀七、更新機(jī)制小程序冷啟動(dòng)時(shí)如果發(fā)現(xiàn)有新版本,將會(huì)異步下載新版本的代碼包,并同時(shí)用客戶端本地的包進(jìn)行啟動(dòng),即新版本的小程序需要等下一次冷啟動(dòng)才會(huì)應(yīng)用上。
如果需要馬上應(yīng)用最新版本,可以使用 wx.getUpdateManager API 進(jìn)行處理。
八、性能優(yōu)化主要的優(yōu)化策略可以歸納為三點(diǎn):
精簡(jiǎn)代碼,降低WXML結(jié)構(gòu)和JS代碼的復(fù)雜性;合理使用setData調(diào)用,減少setData次數(shù)和數(shù)據(jù)量;必要時(shí)使用分包優(yōu)化。
1、setData 工作原理小程序的視圖層目前使用 WebView 作為渲染載體,而邏輯層是由獨(dú)立的 JavascriptCore 作為運(yùn)行環(huán)境。
在架構(gòu)上,WebView 和 JavascriptCore 都是獨(dú)立的模塊,并不具備數(shù)據(jù)直接共享的通道。
當(dāng)前,視圖層和邏輯層的數(shù)據(jù)傳輸,實(shí)際上通過兩邊提供的 evaluateJavascript 所實(shí)現(xiàn)。
即用戶傳輸?shù)臄?shù)據(jù),需要將其轉(zhuǎn)換為字符串形式傳遞,同時(shí)把轉(zhuǎn)換后的數(shù)據(jù)內(nèi)容拼接成一份 JS 腳本,再通過執(zhí)行 JS 腳本的形式傳遞到兩邊獨(dú)立環(huán)境。
而 evaluateJavascript 的執(zhí)行會(huì)受很多方面的影響,數(shù)據(jù)到達(dá)視圖層并不是實(shí)時(shí)的。
2、常見的 setData 操作錯(cuò)誤頻繁的去 setData在我們分析過的一些案例里,部分小程序會(huì)非常頻繁(毫秒級(jí))的去setData,其導(dǎo)致了兩個(gè)后果:
Android下用戶在滑動(dòng)時(shí)會(huì)感覺到卡頓,操作反饋延遲嚴(yán)重,因?yàn)?JS 線程一直在編譯執(zhí)行渲染,未能及時(shí)將用戶操作事件傳遞到邏輯層,邏輯層亦無法及時(shí)將操作處理結(jié)果及時(shí)傳遞到視圖層;渲染有出現(xiàn)延時(shí),由于 WebView 的 JS 線程一直處于忙碌狀態(tài),邏輯層到頁面層的通信耗時(shí)上升,視圖層收到的數(shù)據(jù)消息時(shí)距離發(fā)出時(shí)間已經(jīng)過去了幾百毫秒,渲染的結(jié)果并不實(shí)時(shí);每次 setData 都傳遞大量新數(shù)據(jù)由setData的底層實(shí)現(xiàn)可知,我們的數(shù)據(jù)傳輸實(shí)際是一次 evaluateJavascript腳本過程,當(dāng)數(shù)據(jù)量過大時(shí)會(huì)增加腳本的編譯執(zhí)行時(shí)間,占用 WebView JS 線程, 后臺(tái)態(tài)頁面進(jìn)行 setData當(dāng)頁面進(jìn)入后臺(tái)態(tài)(用戶不可見),不應(yīng)該繼續(xù)去進(jìn)行setData,后臺(tái)態(tài)頁面的渲染用戶是無法感受的,另外后臺(tái)態(tài)頁面去setData也會(huì)搶占前臺(tái)頁面的執(zhí)行。
總結(jié)大致從以上幾個(gè)角度分析了小程序的底層架構(gòu),從小程序的由來、到雙線程的出現(xiàn)、設(shè)計(jì)、通信、到基礎(chǔ)庫(kù)、Exparser 框架、再到運(yùn)行機(jī)制、性能優(yōu)化等等,都是一個(gè)個(gè)相關(guān)而又相互影響的選擇。
關(guān)于小程序的底層框架設(shè)計(jì),應(yīng)該還有很多,每一個(gè)框架的誕生都有其意義,我們作為開發(fā)者能做的不只是會(huì)使用這個(gè)工具,還應(yīng)理解它的設(shè)計(jì)模式。
只有這樣才不會(huì)被工具左右,才能走的更遠(yuǎn)!以上就是淺析小程序運(yùn)行機(jī)制的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!
微信
分享相關(guān)標(biāo)簽:
小程序本文轉(zhuǎn)載于:
csdn,如有侵犯,請(qǐng)聯(lián)系[email protected]刪除
上一篇:
微信小程序怎么實(shí)現(xiàn)九宮格跳轉(zhuǎn)
下一篇:
微信小程序刮刮卡的實(shí)現(xiàn)相關(guān)文章相關(guān)視頻微信小程序如何開發(fā)一款小游戲?(實(shí)戰(zhàn)教程)小程序如何接入微信支付?(開發(fā)教程介紹)小程序中如何管理session?小程序支付秘鑰在哪里設(shè)置淺析小程序運(yùn)行機(jī)制認(rèn)識(shí)小程序的目錄結(jié)構(gòu)小程序的rpx長(zhǎng)度單位詳解布局奔牛課堂小程序搜素框小程序文檔 [溫州做小程序]
為您推薦
- 百度智能小程序SWAN 視圖基礎(chǔ)數(shù)據(jù)綁定怎么做 2020-08-24
- 百度智能小程序SWAN 視圖是什么? 2020-08-24
- 百度智能小程序啟動(dòng)頁面的代碼如何設(shè)置 2020-08-24
- 百度智能小程序SWAN 生命周期是什么 2020-08-24
- 百度智能小程序如何配置全局?jǐn)?shù)據(jù) 2020-08-24
- 百度智能小程序?window、tabBar如何優(yōu)化和調(diào)整 2020-08-24
- 百度智能小程序?pages是什么 2020-08-24
- 百度智能小程序配置界面、路徑如何優(yōu)化 2020-08-24