微信小程序原理

微信小程序使用了前端技術(shù)棧。JavaScript/WXML/WXSS它背后的原理是怎么樣的呢?微信小程序使用了前端技術(shù)棧 JavaScript/WXML/WXSS。

但和常規(guī)的前端開(kāi)發(fā)又有一些區(qū)別:

JavaScript: 微信小程序的 JavaScript 運(yùn)行環(huán)境即不是 Browser 也不是 Node.js。它運(yùn)行在微信 App 的上下文中,不能操作 Browser context 下的 DOM,也不能通過(guò) Node.js 相關(guān)接口訪問(wèn)操作系統(tǒng) API。所以,嚴(yán)格意義來(lái)講,微信小程序并不是 Html5,雖然開(kāi)發(fā)過(guò)程和用到的技術(shù)棧和 Html5 是相通的。WXML: 作為微信小程序的展示層,并不是使用 Html,而是自己發(fā)明的基于 XML 語(yǔ)法的描述。WXSS: 用來(lái)修飾展示層的樣式。官方的描述是 “ WXSS (WeiXin Style Sheets) 是一套樣式語(yǔ)言,用于描述 WXML 的組件樣式。WXSS 用來(lái)決定 WXML 的組件應(yīng)該怎么顯示?!?“我們的 WXSS 具有 CSS 大部分特性...我們對(duì) CSS 進(jìn)行了擴(kuò)充以及修改?!被?CSS2 還是 CSS3?大部分是哪些部分?是否支持 CSS3 里的動(dòng)畫(huà)?不得而知。在微信小程序官方文檔上,有下面這段話:微信小程序運(yùn)行在三端:iOS、Android 和 用于調(diào)試的開(kāi)發(fā)者工具在 iOS 上,小程序的 javascript 代碼是運(yùn)行在JavaScriptCore 中在 Android 上,小程序的 javascript 代碼是通過(guò) X5 內(nèi)核來(lái)解析在 開(kāi)發(fā)工具上, 小程序的 javascript 代碼是運(yùn)行在 nwjs(chrome內(nèi)核)開(kāi)發(fā)工具小程序的 javascript 代碼運(yùn)行在 nwjs 中。nwjs 是什么鬼呢?官方介紹是這樣寫(xiě)的:NW.js (previously known as node-webkit) lets you call all Node.js modules directly from DOM and enables a new way of writing applications with all Web technologies.nwjs 合并 Browser 和 Node.js 的運(yùn)行時(shí),可以使用前端開(kāi)發(fā)技術(shù)來(lái)開(kāi)發(fā)跨平臺(tái)的應(yīng)用程序。借助 Node.js 訪問(wèn)操作系統(tǒng)原生 API 的能力,可以開(kāi)發(fā)中跨平臺(tái)的應(yīng)用程序。微信小程序開(kāi)發(fā)工具就是使用 nwjs 開(kāi)發(fā)的。如果你是 Mac 用戶,進(jìn)入目錄 /Applications/wechatwebdevtools.app/Contents/Resources/app.nw/app 可以看到開(kāi)發(fā)工具的實(shí)現(xiàn)代碼,當(dāng)然代碼是經(jīng)過(guò)混淆的。網(wǎng)上流行的破解版本開(kāi)發(fā)工具原理上就是修改這里面的代碼。與此類(lèi)似的,一個(gè)更火的項(xiàng)目是 Electron,由 GitHub 推出的,它也是把 Browser 和 Node.js 結(jié)合,用來(lái)開(kāi)發(fā)跨平臺(tái)的應(yīng)用程序。程序員們應(yīng)該聽(tīng)說(shuō)過(guò) Atom 這個(gè)編輯器界的后起之秀。包括微軟擁抱開(kāi)源社區(qū)的編輯器 vscode 也是使用 Electron 開(kāi)發(fā)的。Electron vs nwjs

這兩個(gè)平臺(tái)有什么區(qū)別?為什么微信選擇 nwjs 呢?我們不妨猜一猜。從技術(shù)角度來(lái)講:應(yīng)用程序入口不同:Electron 入口是一個(gè) javascript 腳本,腳本里要自己負(fù)責(zé)創(chuàng)建瀏覽器窗口,加載 html 頁(yè)面。而 nwjs 的入口就是一個(gè) html 頁(yè)面,框架自己會(huì)創(chuàng)建瀏覽器窗口來(lái)顯示這個(gè) html 頁(yè)面。Node.js 集成方式不同:Electron 直接使用 Node.js 的共享庫(kù),不需要修改 Chromium 代碼。

而 nwjs 為了集成 Node.js ,需要修改 Chromium 代碼,以便在瀏覽器里能通過(guò) Node.js 訪問(wèn)系統(tǒng)原生 API。Multi-Context: nwjs 有多個(gè)上下文,一個(gè)是瀏覽器的上下文,用來(lái)訪問(wèn) Browser 相關(guān) API,比如操作 DOM ,另外一個(gè)是 Node 上下文,用來(lái)訪問(wèn)操作系統(tǒng) API。Electron 沒(méi)有使用多個(gè)上下文,對(duì)開(kāi)發(fā)者更友好。從應(yīng)用角度來(lái)講:打包后的文件大小:Electron 打包后文件會(huì)比 nwjs 小不少。一個(gè) 18M 的程序,使用 Electron 打包后是 117M,而使用 nwjs 打包后的程序是 220M。微信小程序開(kāi)發(fā)工具打包后是 219M (v0.10.102800)。沒(méi)有親測(cè),評(píng)價(jià)來(lái)源參考文檔。代碼保護(hù):Electron 只支持代碼混淆來(lái)保護(hù),而 nwjs 把核心代碼放在 V8 引擎里,不但可以保護(hù)代碼,還可以提高執(zhí)行效率。開(kāi)源社區(qū)活躍度:Electron 應(yīng)該是完勝的??纯词褂?Electron 構(gòu)建的應(yīng)用程序就知道了。而據(jù)說(shuō) nwjs 的開(kāi)發(fā)文檔有些都沒(méi)有及時(shí)更新。應(yīng)用程序啟動(dòng)時(shí)間:Electron 會(huì)稍微快一點(diǎn)。沒(méi)有親測(cè),評(píng)價(jià)來(lái)源參考文檔。從這個(gè)分析猜測(cè),微信選擇 nwjs 的原因可能是出于代碼保護(hù)。畢竟開(kāi)發(fā)工具可以上傳小程序,有些接口和數(shù)據(jù)需要比較嚴(yán)密的保護(hù)。哪位大牛可以挖挖看哪些代碼被保護(hù)起來(lái)了。總結(jié)微信小程序最大的好處是不需要做設(shè)備適配,只要微信能運(yùn)行,小程序就能運(yùn)行。小程序雖然是一個(gè)封閉形態(tài)下的前端開(kāi)發(fā)技術(shù),但借助微信的巨大影響力,幾乎所有人都在往里面沖。微信小程序太火了,內(nèi)測(cè)火,公測(cè)更火。內(nèi)測(cè)剛出來(lái),就有人用微信小程序?qū)崿F(xiàn)了商城,并開(kāi)源。感嘆一下:你的熱情,就像一把火,燃燒了整個(gè)沙漠。

作為開(kāi)發(fā)者,提幾個(gè)不足:不支持從 node_modules 中加載模塊。這樣無(wú)形中就把 npm 排除在外了。從開(kāi)發(fā)生態(tài)角度,這個(gè)應(yīng)該是微信小程序下一步要重點(diǎn)解決的問(wèn)題吧。開(kāi)發(fā)工具自帶的代碼編輯器還是太簡(jiǎn)陋了。不知道為什么微信要重復(fù)發(fā)明輪子。理論上,給流行的代碼編輯器 (sublime/atom/vscode etc.) 開(kāi)發(fā)個(gè)插件。然后用戶直接到小程序后臺(tái)上傳提交審核就好了。程序員是挑剔到近乎偏執(zhí)的物種,代碼編輯器又是程序員時(shí)刻打交道的工具,要做好實(shí)屬不易。真機(jī)運(yùn)行環(huán)境

下面內(nèi)容完全是猜測(cè)的,如有言中,實(shí)屬運(yùn)氣。微信小程序的運(yùn)行環(huán)境應(yīng)該更類(lèi)似 ReactNative 之類(lèi),而不是純 Html5。兩者最大的不同在于,ReactNative 的界面是由原生控件渲染出來(lái)的,而 Html5 的界面是由瀏覽器內(nèi)核渲染出來(lái)的。兩者在性能上有較大的差異,感興趣的可以參閱我的另外一篇文章《跨平臺(tái) App 開(kāi)發(fā)技術(shù)方案匯總》。原理上,小程序是如何在微信 App 里運(yùn)行的呢?微信 App 里包含 javascript 運(yùn)行引擎。微信 App 里包含了 WXML/WXSS 處理引擎,最終會(huì)把界面翻譯成系統(tǒng)原生的控件,并展示出來(lái)。這樣做的目的是為了提供和原生 App 性能相當(dāng)?shù)挠脩趔w驗(yàn)。我們來(lái)意淫一下小程序加載運(yùn)行的過(guò)程:用戶點(diǎn)擊打開(kāi)一個(gè)小程序微信 App 從微信服務(wù)器下載這個(gè)小程序分析 app.json 得到應(yīng)用程序的配置信息(導(dǎo)航欄,窗口樣式,包含的頁(yè)面列表等)加載并運(yùn)行 app.js加載并顯示在 app.json 里配置的第一個(gè)頁(yè)面這個(gè)只是從開(kāi)發(fā)者眼中看到的一個(gè)簡(jiǎn)化版的過(guò)程,實(shí)際過(guò)程應(yīng)該比這要復(fù)雜得多,涉及到瀏覽器線程(就是運(yùn)行我們的邏輯層代碼 app.js 等的線程)和 AppService 線程之間的交互。

生命周期至于微信 App 是如何與小程序的邏輯層 javascript 交互的呢?

可以簡(jiǎn)單地歸納如下:JavaScript 是腳本語(yǔ)言,可以在運(yùn)行時(shí)解釋并執(zhí)行。微信 App 里包含了一個(gè) JavaScript 引擎,由它來(lái)負(fù)責(zé)執(zhí)行邏輯層的 JavaScript 代碼。那么 JavaScript 調(diào)用的小程序相關(guān) API 怎么實(shí)現(xiàn)的呢?答案是最終會(huì)被翻譯成實(shí)現(xiàn)在微信 App 里的原生接口。比如開(kāi)發(fā)者調(diào)用 wx.getLocation(OBJECT) 獲取當(dāng)前地理位置,微信 App 里的 JavaScript 引擎在執(zhí)行這個(gè)代碼時(shí),會(huì)去調(diào)用微信 App 里實(shí)現(xiàn)的原生接口來(lái)獲取地理位置坐標(biāo)。感興趣的朋友可以閱讀我之前推薦過(guò)的一篇文章《React Native 從入門(mén)到原理》。文章分析的雖然是 ReactNative,但實(shí)際上原理是相通的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 微信小程序使用了前端技術(shù)棧 JavaScript/WXML/WXSS。它背后的原理是怎么樣的呢? 寫(xiě)在前面 微信小...
    kamidox閱讀 43,021評(píng)論 10 88
  • 你也在玩小程序?這些基本原理你知道嗎? 微信小程序使用了前端技術(shù)棧JavaScript/WXML/WXSS。...
    奮斗的憤青i閱讀 2,213評(píng)論 0 4
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,905評(píng)論 25 709
  • ln是一個(gè)很神奇的命令,它可以創(chuàng)建一個(gè)文件的影子,也可以通過(guò)一個(gè)通道進(jìn)入另一個(gè)地方。:)其實(shí),所有的這些把戲都是通...
    shuff1e閱讀 304評(píng)論 0 0
  • 網(wǎng)站: http://code4app.com/ios/Popover-View-in-iPhone/4fa931...
    小小東閱讀 305評(píng)論 0 2

友情鏈接更多精彩內(nèi)容