⁨⁡⁢⁠⁦
WUhTEE⁣⁧⁩⁠
⁤⁩⁦⁢⁦⁢⁦⁩⁨⁦⁧ ⁡⁡⁧⁠⁣⁩⁥⁩⁧
⁠⁥⁤⁧⁠⁦
⁢⁡⁦ isTFNrH⁡⁠⁧⁩⁨⁧⁦⁨⁦⁠ ⁠⁠⁥⁥⁩⁧
⁨⁩⁧⁡⁩
⁦⁠⁥⁧ gPyVU0⁤⁡⁦⁥⁣ ⁦⁦⁨⁤⁦⁧
⁤⁢
⁠⁡⁩⁧⁤⁩⁨ ⁨⁣⁤⁨⁦⁩⁥⁣⁦ ⁥⁤⁥⁣⁠⁠⁤⁧⁥ ⁡⁩⁡⁣⁤⁩⁠⁣⁥ NhmVS⁦⁢⁧⁧⁡⁣⁢⁠⁧
⁩⁨⁡⁦⁠⁧⁨⁠⁧
⁥⁦⁠⁩⁤ EpTt⁧⁢⁤⁩⁦⁡ ⁣⁠⁨⁦⁤⁥⁠⁠⁦ ⁡⁥⁨⁥⁦⁤⁤⁣⁩⁠ ⁧⁢⁦⁥⁤⁢ ⁧⁤⁧⁦⁨ ⁤⁣⁥⁢ ⁢
⁦⁧⁧⁥⁦⁩⁠⁤
⁩⁦⁥⁧⁡⁥⁤⁣⁣⁤⁡ ⁨⁨⁢⁩⁨⁨ ⁣⁧⁤⁧⁩⁠⁥⁧
⁥⁧⁢ ⁦⁥⁤⁧⁨⁦⁤⁠⁦⁡⁧ ⁩⁠⁥⁧⁠⁠⁩ ⁩⁠⁡⁧⁢⁡⁦⁥ ⁢⁥⁣⁧⁠ ⁠⁧⁡⁩⁡⁦ 3ERDSs⁨⁡⁥⁣⁤⁥⁧⁩ ⁧⁥⁠
⁡⁤⁢⁦⁥⁨⁣⁡
⁨⁢⁡⁩⁤⁧⁩⁤⁤ ⁨⁦⁥⁢⁥⁧⁥ ⁠⁠⁢⁦ ⁣⁧⁣ ⁡⁧⁧ ⁥⁥⁩⁨⁥⁧⁠ yDkgP⁩⁢⁨⁦ ⁢⁠⁥⁢⁣
⁡⁦⁤⁣⁤⁨
⁢⁥⁣⁦⁨ ⁡⁥⁢⁠ ⁣⁤⁦⁥⁢ ⁢⁤⁩
⁩⁤⁤⁨⁩⁨⁧
⁣⁢⁩⁩⁤⁦⁤ ⁩⁣⁠⁣⁢ ⁠⁣⁤⁡⁨⁥⁧⁦ ⁩⁢⁨⁢⁢⁦⁩
⁡⁤⁧⁥
vBl2t⁠⁠⁡⁩⁣⁢⁦⁩⁧⁧⁢⁥
⁨⁢⁤⁡⁥⁠
⁨⁤⁢⁣⁢⁥⁧⁨

⁤⁢⁩⁨

⁡⁥⁨⁩ ⁨⁡⁠⁢ ⁠⁥⁥⁡⁤⁢⁧⁢ ⁦⁡⁡⁡⁤⁩⁢⁧⁡ ⁡⁦⁧⁠⁥⁢⁣⁩⁨ ⁣⁤⁣⁢⁨⁡⁨⁩⁤⁣ ⁣⁤⁩⁤⁩⁨⁨⁩
⁧⁣⁣⁢⁠⁡⁧⁨
⁧⁠⁦
1WTnh3cFl⁢⁨⁠⁦⁢⁡⁩⁡⁣ jJGrImjQ⁨⁨⁤⁢⁧⁧⁣⁧⁧ M2EWvCE⁤⁨⁧ ⁨⁡⁢⁠⁤⁢⁢⁤⁣⁦⁢⁦ 5KUsRS6l⁩⁧⁡⁠⁤⁡ ⁨⁤⁢⁨⁥⁦ ⁩⁧⁥⁠⁣⁥⁠ ⁨⁥⁡⁢⁨⁥⁨⁩
⁩⁨⁥⁩⁡⁣⁧⁧⁧⁥⁠⁡
⁠⁨⁨⁤⁡⁢⁥⁧⁩⁧⁡ ⁩⁧⁨⁤⁧ ⁢⁣⁩⁥ ⁨⁩⁨⁢⁡ zVdgssQS⁧⁨⁨⁣⁨⁩⁥⁨
    ⁨⁠⁨⁧⁣⁠⁤⁨⁡⁣
⁡⁠⁨⁧
⁥⁤⁥⁡⁩⁩⁢⁩⁤
⁠⁢⁢⁥⁨
⁡⁩⁠⁢⁤⁨⁡

ZFgg⁣⁧⁧

    ⁤⁨⁥
⁩⁦⁠⁨⁣⁨⁩⁩⁠
⁠⁢⁥⁤ ⁦⁦⁨⁩⁧⁡⁧⁡⁩⁢ OJjgW8R⁧⁡⁣⁣⁢⁨ ⁡⁠⁧⁦⁩ ⁧⁤⁤⁠⁦⁦⁩⁣⁧ ⁣⁨⁤⁥⁤⁢ pcqck⁡⁠⁦⁥⁢⁩⁠⁦⁩ ⁨⁠ h5BqQjKPF⁥⁥⁣⁦⁧⁠⁩ ⁢⁥⁤⁥⁦⁩⁤⁢⁦⁩⁣

⁥⁦⁩⁣

⁠⁡⁦⁦ 38zCpO⁣ ⁨⁨⁣⁡⁤⁩⁤ ⁣⁨⁠⁡⁦⁥ ⁨⁣⁨⁡⁧⁨⁢⁧ ⁢⁢⁡⁤⁢
⁣⁧⁡⁥⁠⁤
⁩⁨⁢⁠⁠⁦ dEqGGI⁣⁡⁨⁩⁢⁡⁣⁥⁢ ⁥⁠⁣⁡⁣ ⁩⁢⁥ ⁤⁢⁥⁣⁦⁩⁤⁩⁥⁨⁢
⁠⁩⁣⁨⁥⁨⁥
⁩⁤⁨⁨⁦⁡⁥
⁤⁨⁨⁤⁧⁩⁥⁣⁠⁥⁩
⁨⁧⁩ ⁣⁧⁣⁩⁩⁡ ⁤⁣⁤⁦⁩⁨⁣⁥⁦⁡⁥⁨ eaTZMzbz⁥⁧⁤⁩⁢⁢⁣ ⁣⁦⁩ ⁡⁦⁠ ⁦⁥⁠⁤⁠⁠ ⁦⁤⁩⁢⁧
TQ1Nyzl⁠⁢⁧⁤⁥⁣⁨⁢
⁡⁢⁨⁠⁩⁠
⁢⁣⁧⁡
jyREor⁣⁥⁥⁨⁣⁤
⁧⁤⁨
⁩⁨⁣⁩⁤
⁧⁨⁧⁦⁨⁣⁦⁡⁤ ⁧⁩⁩⁥⁦
⁧⁨⁡⁠⁧⁣
⁧⁩⁣⁣ ⁧⁨⁥⁡⁥⁩⁦⁨⁧
⁢⁨⁦⁠⁢⁨⁣⁡⁢⁣
⁩⁨⁣⁦⁨ ⁠⁠⁢⁡ ⁢⁧⁥⁨⁦⁢ ⁦⁨⁨ ⁤⁢⁣⁥⁩⁦⁣ ⁣⁢⁦⁥⁧⁩⁣⁧ ⁡⁧⁦ ⁠⁩⁢ miofal⁢⁨⁠⁣⁠⁣ ⁨⁥⁦⁡ ⁢⁧
⁠⁠⁥⁨
⁠⁩⁧⁥⁢⁩⁩⁥ ⁨⁦⁥⁥⁦⁦⁥⁩⁧⁨⁧ ⁦⁣⁧⁨⁨⁥
⁦⁢⁩⁨⁨⁠⁥⁧
⁡⁨⁥⁧⁩⁦⁤ ⁨⁡⁡⁤⁧ ⁨⁨⁧⁩⁡ l7H4xF2VRx⁣⁢⁩

⁨⁡⁣⁦⁡⁢⁥

⁠ n3Llu9aQv⁩⁦
⁤⁣⁥⁢⁣
⁣⁤⁤⁧ uXQh⁧⁦⁤⁣ ⁩ ⁢⁡⁦⁢⁧⁨⁡ ⁨⁦⁢⁢⁡⁣⁩⁧⁢⁨⁩ 7hDHGYPj⁣⁨⁦⁨⁤⁩⁦⁢
⁤⁤⁩⁧⁠⁥⁡
ohLhsHYFJ⁦⁧⁧⁧⁣ ⁩⁢⁡⁢

微信(xìn)小程序基礎架構淺析

作(zuò)者(zhě):billgong,騰訊IEG前(qián)端開(kāi)發(fà)工程师。

微信(xìn)小程序,簡稱小程序,英文(wén) mini program。是(shì)一種(zhǒng)不(bù)需要(yào)下(xià)载安(ān)裝(zhuāng)即可(kě)在(zài)微信(xìn)中使用(yòng)的(de)應(yìng)用(yòng),用(yòng)戶掃描小程序碼或(huò)搜索小程序即可(kě)打(dǎ)開(kāi),觸手(shǒu)可(kě)及(jí),用(yòng)完即走(zǒu),不(bù)用(yòng)關(guān)心(xīn)是(shì)否安(ān)裝(zhuāng)太多(duō)應(yìng)用(yòng)的(de)問(wèn)題(tí)。

小程序技術(shù)演進(jìn)

内部(bù)開(kāi)放(fàng)微信(xìn)原生能(néng)力


图(tú)片(piàn)

使用(yòng) WeixinJSBridge 預覽图(tú)片(piàn)

此(cǐ)類(lèi) API 最初是(shì)提(tí)供給(gěi)騰訊内部(bù)一些(xiē)业務(wù)使用(yòng),很多(duō)外(wài)部(bù)開(kāi)發(fà)者(zhě)發(fà)現(xiàn)了之(zhī)後(hòu),依葫蘆画(huà)瓢地(dì)使用(yòng)了,逐漸成为(wèi)微信(xìn)中网页(yè)開(kāi)發(fà)的(de)事實(shí)标(biāo)準。

JS-SDK 發(fà)布(bù)

2015 年(nián)初,微信(xìn)發(fà)布(bù)了一整套(tào)网页(yè)開(kāi)發(fà)工具包(bāo),稱之(zhī)为(wèi) JS-SDK,開(kāi)放(fàng)了拍攝、录(lù)音(yīn)、語(yǔ)音(yīn)識别、二(èr)維碼、地(dì)图(tú)、支付、分(fēn)享、卡(kǎ)券等幾(jǐ)十(shí)个(gè) API。讓所有(yǒu)開(kāi)發(fà)者(zhě)都可(kě)以(yǐ)使用(yòng)到(dào)微信(xìn)的(de)原生能(néng)力。

图(tú)片(piàn)使用(yòng) JS-SDK 调用(yòng)图(tú)片(piàn)預覽組件(jiàn)

JS-SDK 解(jiě)决了移動(dòng)网页(yè)使用(yòng)微信(xìn)能(néng)力不(bù)足的(de)問(wèn)題(tí),通(tòng)过(guò)暴露(lù)微信(xìn)的(de)接口(kǒu)使得 Web 開(kāi)發(fà)者(zhě)能(néng)夠拥有(yǒu)更多(duō)的(de)能(néng)力,然而(ér)在(zài)更多(duō)的(de)能(néng)力之(zhī)外(wài),JS-SDK 的(de)模式並(bìng)沒(méi)有(yǒu)解(jiě)决使用(yòng)移動(dòng)网页(yè)遇到(dào)的(de)體(tǐ)验(yàn)不(bù)良的(de)問(wèn)題(tí)。

JS-SDK 的(de)不(bù)足

用(yòng)戶在(zài)訪問(wèn)网页(yè)的(de)时(shí)候,在(zài)浏覽器開(kāi)始顯示之(zhī)前(qián)都会(huì)有(yǒu)一个(gè)白(bái)屏的(de)过(guò)程,在(zài)移動(dòng)端,受限于(yú)設備性(xìng)能(néng)和(hé)网絡速度(dù),白(bái)屏会(huì)更加明(míng)顯。除了白(bái)屏,影响 Web 體(tǐ)验(yàn)的(de)問(wèn)題(tí)還(huán)有(yǒu)缺少(shǎo)操作(zuò)的(de)反(fǎn)饋,主要(yào)表(biǎo)現(xiàn)在(zài)两(liǎng)个(gè)方(fāng)面(miàn):页(yè)面(miàn)切(qiè)換的(de)生硬(yìng)和(hé)點(diǎn)擊的(de)遲滞感(gǎn)。

图(tú)片(piàn)加载白(bái)屏,切(qiè)換不(bù)流暢

此(cǐ)外(wài)一些(xiē)開(kāi)發(fà)者(zhě)会(huì)使用(yòng) JS-SDK 做一些(xiē),比如(rú)假紅(hóng)包(bāo),僞造的(de)官方(fāng)活動(dòng)等。並(bìng)利用(yòng) JS-SDK 的(de)分(fēn)享能(néng)力变相的(de)去(qù)裂变分(fēn)享到(dào)各(gè)个(gè)群(qún)或(huò)者(zhě)朋友圈,由(yóu)于(yú) JS-SDK 是(shì)根(gēn)據(jù)域名(míng)来(lái)賦予 api 權限的(de),运營人(rén)員封了一个(gè)域名(míng)後(hòu),他(tā)们(men)立馬用(yòng)别的(de)域名(míng)又繼續做壞,要(yào)知道(dào)注册(cè)一个(gè)新(xīn)的(de)域名(míng)的(de)成本(běn)是(shì)很低(dī)的(de)。

图(tú)片(piàn)

那(nà)麼(me)小程序是(shì)通(tòng)过(guò)怎樣(yàng)的(de)設計(jì)来(lái)改進(jìn) JS-SDK 的(de)體(tǐ)验(yàn)和(hé)管(guǎn)控上(shàng)的(de)不(bù)足?

 

小程序双(shuāng)線(xiàn)程架構

具體(tǐ)實(shí)現(xiàn)上(shàng)小程序采用(yòng)了類(lèi) web + 離線(xiàn)包(bāo)的(de)形式。開(kāi)發(fà)上(shàng)與(yǔ) web 類(lèi)似,門(mén)檻較低(dī),開(kāi)發(fà)效率較高。離線(xiàn)下(xià)载和(hé)页(yè)面(miàn)預渲染功能(néng)增強(qiáng)了用(yòng)戶體(tǐ)验(yàn),提(tí)升(shēng)了加载速度(dù),解(jiě)决了 JS-SDK 加载白(bái)屏的(de)問(wèn)題(tí) 1。小程序提(tí)供了云端更新(xīn)離線(xiàn)包(bāo)的(de)功能(néng),可(kě)動(dòng)态更新(xīn)页(yè)面(miàn),相对(duì)于(yú) app 的(de)更新(xīn)和(hé)發(fà)布(bù)更为(wèi)靈活。此(cǐ)外(wài),小程序在(zài)離線(xiàn)包(bāo)的(de)基礎上(shàng)对(duì)切(qiè)換動(dòng)画(huà)進(jìn)行優化,降低(dī)了切(qiè)換页(yè)面(miàn)導致(zhì)的(de)遲滞感(gǎn),缓解(jiě)了切(qiè)換不(bù)流暢的(de)問(wèn)題(tí) 2。

图(tú)片(piàn)小程序web+離線(xiàn)包(bāo)模式

小程序在(zài)架構方(fāng)面(miàn)最大(dà)的(de)特(tè)點(diǎn)是(shì)采用(yòng)了双(shuāng)線(xiàn)程的(de)開(kāi)發(fà)模式,隔離了 JS 邏輯和(hé) UI 渲染。小程序的(de)渲染层(céng)和(hé)邏輯层(céng)分(fēn)别由(yóu) 2 个(gè)線(xiàn)程管(guǎn)理:渲染层(céng)的(de)界面(miàn)使用(yòng)了 WebView 進(jìn)行渲染,邏輯层(céng)采用(yòng) JsCore 線(xiàn)程运行 JS 腳(jiǎo)本(běn)。

邏輯层(céng):創建一个(gè)單獨的(de)線(xiàn)程去(qù)執行 JavaScript,在(zài)这(zhè)个(gè)环(huán)境下(xià)執行的(de)都是(shì)有(yǒu)關(guān)小程序业務(wù)邏輯的(de)代(dài)碼;
渲染层(céng)
:界面(miàn)渲染相關(guān)的(de)任務(wù)全(quán)都在(zài) WebView 線(xiàn)程里(lǐ)執行,通(tòng)过(guò)邏輯层(céng)代(dài)碼去(qù)控制渲染哪些(xiē)界面(miàn)。一个(gè)小程序存在(zài)多(duō)个(gè)界面(miàn),所以(yǐ)渲染层(céng)存在(zài)多(duō)个(gè) WebView 線(xiàn)程;
通(tòng)信(xìn)
:这(zhè)两(liǎng)个(gè)線(xiàn)程的(de)通(tòng)信(xìn)会(huì)經(jīng)由(yóu)微信(xìn)客戶端(下(xià)文(wén)中也会(huì)采用(yòng) Native 来(lái)代(dài)指微信(xìn)客戶端)做中轉(zhuǎn),邏輯层(céng)發(fà)送网絡請求也經(jīng)由(yóu) Native 轉(zhuǎn)發(fà),小程序的(de)通(tòng)信(xìn)模型下(xià)图(tú)所示。

图(tú)片(piàn)小程序双(shuāng)線(xiàn)程架構

JS 邏輯层(céng)运行在(zài) JSCore 中,並(bìng)沒(méi)有(yǒu)一个(gè)完整浏覽器对(duì)象,因(yīn)而(ér)缺少(shǎo)相關(guān)的(de) DOM API 和(hé) BOM API,無法(fǎ)操作(zuò)页(yè)面(miàn)元素,能(néng)达(dá)到(dào)管(guǎn)控的(de)目的(de),但也限制了開(kāi)發(fà)者(zhě)的(de)權限:

  1. 不(bù)允許開(kāi)發(fà)者(zhě)把(bǎ)页(yè)面(miàn)跳轉(zhuǎn)到(dào)其(qí)他(tā)在(zài)線(xiàn)网页(yè)
  2. 不(bù)允許開(kāi)發(fà)者(zhě)直(zhí)接訪問(wèn) DOM
  3. 不(bù)允許開(kāi)發(fà)者(zhě)随意(yì)使用(yòng) window 上(shàng)的(de)某些(xiē)未知的(de)可(kě)能(néng)有(yǒu)危險的(de) API

这(zhè)樣(yàng)的(de)邏輯层(céng)與(yǔ) UI 层(céng)的(de)隔離,加上(shàng)小程序的(de)審核和(hé)舉報機(jī)制,使得微信(xìn)加強(qiáng)对(duì)小程序的(de)管(guǎn)控,解(jiě)决了問(wèn)題(tí) 3。但这(zhè)也使得開(kāi)發(fà)者(zhě)無法(fǎ)靈活的(de)進(jìn)行页(yè)面(miàn)渲染。

 

小程序页(yè)面(miàn)渲染

上(shàng)面(miàn)已經(jīng)说(shuō)了邏輯层(céng)無法(fǎ)操作(zuò) DOM 变更,那(nà)小程序是(shì)如(rú)何進(jìn)行页(yè)面(miàn)的(de)渲染呢?小程序基于(yú)數據(jù)驅動(dòng)的(de)架構模式,基于(yú) Virtual Dom(React 引入(rù),真(zhēn)實(shí) DOM 的(de)一種(zhǒng) JS 描述方(fāng)式)的(de)概念,业務(wù)侧只(zhī)需要(yào)改变數據(jù)即可(kě)引起(qǐ)界面(miàn)变化。其(qí)中渲染层(céng)提(tí)供了带(dài)有(yǒu)數據(jù)綁定(dìng)語(yǔ)法(fǎ)的(de) WXML,邏輯层(céng)提(tí)供了setData 等等 API,開(kāi)發(fà)者(zhě)需要(yào)進(jìn)行界面(miàn)变化时(shí),只(zhī)需要(yào)通(tòng)过(guò)在(zài)邏輯层(céng)執行 setData 把(bǎ)变化的(de)數據(jù)通(tòng)过(guò) Native 层(céng)传遞到(dào)渲染层(céng),小程序会(huì)進(jìn)行 Dom Diff(DOM 結構对(duì)比並(bìng)進(jìn)行最小化变更的(de)算法(fǎ))等流程,最後(hòu)把(bǎ)正(zhèng)确的(de)結果(guǒ)更新(xīn)在(zài) Dom 樹(shù)上(shàng)。

图(tú)片(piàn)小程序Virtual DOM渲染

完整的(de)通(tòng)信(xìn)流程大(dà)致(zhì)如(rú)下(xià):

  1. 邏輯层(céng)调用(yòng)宿主环(huán)境的(de) setData 方(fāng)法(fǎ)。
  2. 邏輯层(céng)将待传輸數據(jù)轉(zhuǎn)換成字(zì)符串,並(bìng)拼接到(dào)特(tè)定(dìng)的(de) JS 腳(jiǎo)本(běn),最後(hòu)将數據(jù)传輸到(dào)渲染层(céng)。
  3. 渲染层(céng)接收(shōu)到(dào)後(hòu),WebView JS 線(xiàn)程会(huì)对(duì)腳(jiǎo)本(běn)進(jìn)行編譯,得到(dào)待更新(xīn)數據(jù)後(hòu)進(jìn)入(rù)渲染队列,等待 WebView 線(xiàn)程空(kōng)閑时(shí)進(jìn)行页(yè)面(miàn)渲染。
  4. WebView 線(xiàn)程開(kāi)始執行渲染时(shí),待更新(xīn)數據(jù)会(huì)合並(bìng)到(dào)視图(tú)层(céng)保留的(de)原始 data 數據(jù),並(bìng)将新(xīn)數據(jù)套(tào)用(yòng)在(zài) WXML 片(piàn)段(duàn)中得到(dào)新(xīn)的(de)虛拟节(jié)點(diǎn)樹(shù)。經(jīng)过(guò)新(xīn)虛拟节(jié)點(diǎn)樹(shù)與(yǔ)當前(qián)节(jié)點(diǎn)樹(shù)的(de) diff 对(duì)比,将差异(yì)部(bù)分(fēn)更新(xīn)到(dào) UI 視图(tú)。同(tóng)时(shí)将新(xīn)的(de)节(jié)點(diǎn)樹(shù)替換旧节(jié)點(diǎn)樹(shù),用(yòng)于(yú)下(xià)一次(cì)重(zhòng)渲染。

小程序方(fāng)案(àn)與(yǔ) React Native 对(duì)比

那(nà)麼(me)小程序與(yǔ)現(xiàn)有(yǒu)的(de)混合開(kāi)發(fà)技術(shù)類(lèi)型的(de)异(yì)同(tóng)點(diǎn)在(zài)哪?尤其(qí)是(shì)與(yǔ) React Native 的(de)區(qū)别,小程序技術(shù)架構为(wèi)什(shén)麼(me)沒(méi)有(yǒu)使用(yòng) React Native?

混合開(kāi)發(fà)技術(shù)類(lèi)型

現(xiàn)有(yǒu)的(de)混合開(kāi)發(fà)類(lèi)型,基于(yú) UI 渲染的(de)分(fēn)類(lèi)来(lái)看(kàn),主要(yào)有(yǒu)两(liǎng)類(lèi):

  1. 基于(yú) WebView UI 的(de)基礎方(fāng)案(àn)。市(shì)面(miàn)上(shàng)主流,例如(rú)微信(xìn) JS-SDK,通(tòng)过(guò) JSBridge 完成 H5 和(hé) Native 的(de)双(shuāng)向(xiàng)通(tòng)訊,從而(ér)賦予 H5 一定(dìng)的(de)原生能(néng)力。
  2. 基于(yú) Native UI 的(de)方(fāng)案(àn),例如(rú) React-Native、Weex、Flutter 等。在(zài)賦予 H5 原生 API 能(néng)力的(de)基礎上(shàng),進(jìn)一步通(tòng)过(guò) JSBridge 将 JS 解(jiě)析成虛拟 DOM 传遞到(dào) Native,並(bìng)使用(yòng)原生渲染。

小程序也属于(yú)類(lèi)型 1,本(běn)次(cì)我(wǒ)们(men)主要(yào)以(yǐ)類(lèi)型 2 中的(de) React Native 作(zuò)为(wèi)对(duì)比分(fēn)析。

React Native 技術(shù)架構

框架

React Native 框架主要(yào)有(yǒu)三(sān)层(céng):

  1. JS 层(céng):該层(céng)提(tí)供了各(gè)種(zhǒng)供開(kāi)發(fà)者(zhě)使用(yòng)的(de)組件(jiàn)以(yǐ)及(jí)一些(xiē)工具庫(事件(jiàn)分(fēn)發(fà)等)。
  2. C++层(céng):主要(yào)處(chù)理 java/OC 與(yǔ) JS 的(de)通(tòng)信(xìn)(JSBridge)以(yǐ)及(jí)執行 JavaScript(JS 腳(jiǎo)本(běn)引擎)。
  3. Native 层(céng)(Object C/Java 层(céng)):主要(yào)包(bāo)括 UI 渲染器、网絡通(tòng)信(xìn)等工具庫。根(gēn)據(jù)不(bù)同(tóng)操作(zuò)系(xì)統有(yǒu)不(bù)同(tóng)的(de)實(shí)現(xiàn)。
UI 渲染

React Native 基于(yú) react 框架(Virtual Dom)来(lái)進(jìn)行 UI 渲染,具體(tǐ)的(de)流程大(dà)致(zhì)如(rú)下(xià):

  1. 首先(xiān) JS 层(céng)通(tòng)过(guò) JSX 編写(xiě)的(de) Virtual Dom 来(lái)構建 Component
  2. Native 层(céng)将其(qí)轉(zhuǎn)成真(zhēn)實(shí) DOM 插入(rù)到(dào)原生 App 的(de)页(yè)面(miàn)中。
  3. 當有(yǒu)变更,通(tòng)过(guò) diff 算法(fǎ)生成差异(yì)对(duì)象
  4. 最終(zhōng)由(yóu) Native 层(céng)将差异(yì)对(duì)象應(yìng)用(yòng)到(dào)原生 App 的(de)页(yè)面(miàn)元素上(shàng)。
通(tòng)信(xìn)

React Native 基于(yú) JSCore 實(shí)現(xiàn) js 與(yǔ) java/oc 交互,具體(tǐ)流程大(dà)致(zhì)如(rú)下(xià):

  1. 把(bǎ) JSX 代(dài)碼解(jiě)析成 javaScript 代(dài)碼
  2. 读(dú)取(qǔ) JS 文(wén)件(jiàn),並(bìng)利用(yòng)利用(yòng) JS 腳(jiǎo)本(běn)引擎執行
  3. 返回(huí)一个(gè)數組,數組中会(huì)描述 OC/Java 对(duì)象,描述对(duì)象属性(xìng)和(hé)所需要(yào)執行的(de)方(fāng)法(fǎ),这(zhè)樣(yàng)就(jiù)能(néng)讓这(zhè)个(gè)对(duì)象設置属性(xìng),並(bìng)且(qiě)调用(yòng)方(fāng)法(fǎ)。

图(tú)片(piàn)Reactive Native架構

React Native 優缺點(diǎn)

優势
  1. 原生渲染,性(xìng)能(néng)更好(hǎo),用(yòng)戶體(tǐ)验(yàn)較好(hǎo);
  2. React 生态較好(hǎo),对(duì)前(qián)端開(kāi)發(fà)友好(hǎo);
  3. hybrid 技術(shù)跨平台(tái)開(kāi)發(fà),成本(běn)及(jí)難度(dù)低(dī)于(yú)原生;
  4. 可(kě)热(rè)更新(xīn),能(néng)夠方(fāng)便叠代(dài)。
劣势
  1. 支持的(de)樣(yàng)式是(shì) CSS 的(de)子集,会(huì)滿足不(bù)了 Web 開(kāi)發(fà)者(zhě)日(rì)漸增长(cháng)的(de)需求;
  2. 現(xiàn)有(yǒu)能(néng)力下(xià)還(huán)存在(zài)的(de)一些(xiē)不(bù)穩定(dìng)問(wèn)題(tí),比如(rú)性(xìng)能(néng)、Bug 等;
  3. 把(bǎ)渲染工作(zuò)全(quán)都交由(yóu)客戶端原生渲染,会(huì)有(yǒu)更接近(jìn)原生的(de)體(tǐ)验(yàn),但實(shí)際上(shàng)一些(xiē)簡單的(de)界面(miàn)元素使用(yòng) Web 技術(shù)渲染完全(quán)能(néng)勝任;
  4. React Native 之(zhī)前(qián)爆出(chū)了一个(gè)開(kāi)源協議問(wèn)題(tí)(Facebook BSD+Patents ,大(dà)致(zhì)内容是(shì)使用(yòng)基于(yú) Facebook BSD+Patents 協議的(de)開(kāi)源項目的(de)開(kāi)發(fà)者(zhě),未来(lái)要(yào)是(shì)因(yīn)为(wèi)專利問(wèn)題(tí)與(yǔ) Facebook 産生糾紛,那(nà)麼(me) Facebook 将有(yǒu)權停止你使用(yòng)該開(kāi)源項目),这(zhè)对(duì)于(yú)之(zhī)後(hòu)也是(shì)存在(zài)隐患的(de)。

小程序不(bù)選擇 React Native 原因(yīn)

據(jù)小程序開(kāi)發(fà)人(rén)員告知的(de)原因(yīn)如(rú)下(xià):

  1. React Native 只(zhī)支持 CSS 的(de)子集,作(zuò)为(wèi)一个(gè)開(kāi)放(fàng)的(de)生态,需要(yào)告知開(kāi)發(fà)者(zhě)哪些(xiē) CSS 属性(xìng)能(néng)用(yòng),哪些(xiē)不(bù)能(néng)用(yòng),这(zhè)樣(yàng)的(de)開(kāi)發(fà)體(tǐ)验(yàn)較差;(对(duì)應(yìng)上(shàng)面(miàn)的(de)劣势 1
  2. React Native 本(běn)身(shēn)存在(zài)一些(xiē)問(wèn)題(tí),这(zhè)些(xiē)依賴 RN 的(de)修複,同(tóng)时(shí)这(zhè)樣(yàng)就(jiù)变成太过(guò)依賴客戶端發(fà)版本(běn)去(qù)解(jiě)决開(kāi)發(fà)者(zhě)那(nà)邊(biān)的(de) Bug,修複周期(qī)太长(cháng)。(对(duì)應(yìng)上(shàng)面(miàn)的(de)劣势 2
  3. React Native 前(qián)阵(zhèn)子還(huán)搞出(chū)了一个(gè)開(kāi)源協議問(wèn)題(tí),来(lái)说(shuō)也是(shì)存在(zài)隐患的(de)。(对(duì)應(yìng)上(shàng)面(miàn)的(de)劣势 4

小程序與(yǔ) React Native 相同(tóng)點(diǎn)

  1. 都具有(yǒu) hybrid 技術(shù)的(de)優點(diǎn):接近(jìn)原生的(de)體(tǐ)验(yàn),跨平台(tái)開(kāi)發(fà)
  2. 使用(yòng) Web 相關(guān)技術(shù)框架来(lái)編写(xiě)业務(wù)代(dài)碼,React Native 为(wèi) React 框架,小程序为(wèi)小程序開(kāi)發(fà)框架。
  3. 各(gè)自(zì)實(shí)現(xiàn)了跨語(yǔ)言通(tòng)訊方(fāng)案(àn)完成 Native(Java/Objective-c/…)端與(yǔ) JavaScript(小程序中为(wèi)渲染层(céng)和(hé)邏輯层(céng))的(de)通(tòng)訊

小程序與(yǔ) React Native 不(bù)同(tóng)點(diǎn)

小程序使用(yòng)浏覽器内核 WebView 来(lái)渲染界面(miàn)(小部(bù)分(fēn)原生組件(jiàn)由(yóu)客戶端參與(yǔ)渲染),界面(miàn)主要(yào)由(yóu)成熟的(de) Web 技術(shù)渲染,輔之(zhī)大(dà)量(liàng)的(de)接口(kǒu)提(tí)供豐富的(de)客戶端原生能(néng)力,而(ér) React Native 是(shì)客戶端原生渲染。理論上(shàng) React Native 相对(duì)于(yú) WebView 的(de)性(xìng)能(néng)更好(hǎo),但小程序的(de)類(lèi) web 開(kāi)發(fà)对(duì)開(kāi)發(fà)来(lái)说(shuō)入(rù)門(mén)相对(duì)簡單,像是(shì)一種(zhǒng)開(kāi)發(fà)效率與(yǔ)性(xìng)能(néng)的(de)双(shuāng)刃劍。

 

小程序開(kāi)發(fà)注意(yì)事項

基于(yú)上(shàng)面(miàn)的(de)架構分(fēn)析,我(wǒ)们(men)在(zài)開(kāi)發(fà)中需要(yào)注意(yì)是(shì):

  1. 避免使用(yòng)操作(zuò)操作(zuò) DOM 的(de) npm 包(bāo)。由(yóu)于(yú)邏輯层(céng)和(hé)渲染层(céng)隔離,邏輯层(céng)無法(fǎ)操作(zuò) DOM/BOM API,所以(yǐ)需要(yào)使用(yòng) DOM/BOM API 相關(guān)的(de) npm 包(bāo)和(hé)庫中不(bù)可(kě)使用(yòng)。
  2. 避免频繁调用(yòng)setData。由(yóu)于(yú)setData中的(de)數據(jù)不(bù)僅需要(yào)通(tòng)过(guò) Native 层(céng)传遞到(dào)渲染层(céng),通(tòng)过(guò) DOM diff 算法(fǎ)等渲染成最終(zhōng)页(yè)面(miàn),所以(yǐ)需要(yào)盡量(liàng)減少(shǎo)setData的(de)使用(yòng)以(yǐ)避免性(xìng)能(néng)問(wèn)題(tí)。
  3. 避免setData传遞大(dà)量(liàng)的(de)新(xīn)數據(jù)。數據(jù)的(de)传輸会(huì)經(jīng)曆跨線(xiàn)程传輸和(hé)腳(jiǎo)本(běn)編譯的(de)过(guò)程,當數據(jù)量(liàng)过(guò)大(dà),会(huì)增加腳(jiǎo)本(běn)編譯的(de)執行时(shí)間(jiān),占用(yòng) WebView JS 線(xiàn)程,從而(ér)影响到(dào)最終(zhōng)的(de)渲染性(xìng)能(néng)。
日(rì)期(qī):2021-06-22
閱读(dú): 次(cì)
作(zuò)者(zhě):admin
字(zì)體(tǐ):大(dà)
收(shōu)藏 推薦 打(dǎ)印(yìn) | 录(lù)入(rù):admin | 来(lái)源:根(gēn)元环(huán)保
相關(guān)新(xīn)闻      
本(běn)文(wén)評論   查看(kàn)全(quán)部(bù)評論 (0) [發(fà)表(biǎo)評論]
⁨⁡⁢⁠⁦
WUhTEE⁣⁧⁩⁠
⁤⁩⁦⁢⁦⁢⁦⁩⁨⁦⁧ ⁡⁡⁧⁠⁣⁩⁥⁩⁧
⁠⁥⁤⁧⁠⁦
⁢⁡⁦ isTFNrH⁡⁠⁧⁩⁨⁧⁦⁨⁦⁠ ⁠⁠⁥⁥⁩⁧
⁨⁩⁧⁡⁩
⁦⁠⁥⁧ gPyVU0⁤⁡⁦⁥⁣ ⁦⁦⁨⁤⁦⁧
⁤⁢
⁠⁡⁩⁧⁤⁩⁨ ⁨⁣⁤⁨⁦⁩⁥⁣⁦ ⁥⁤⁥⁣⁠⁠⁤⁧⁥ ⁡⁩⁡⁣⁤⁩⁠⁣⁥ NhmVS⁦⁢⁧⁧⁡⁣⁢⁠⁧
⁩⁨⁡⁦⁠⁧⁨⁠⁧
⁥⁦⁠⁩⁤ EpTt⁧⁢⁤⁩⁦⁡ ⁣⁠⁨⁦⁤⁥⁠⁠⁦ ⁡⁥⁨⁥⁦⁤⁤⁣⁩⁠ ⁧⁢⁦⁥⁤⁢ ⁧⁤⁧⁦⁨ ⁤⁣⁥⁢ ⁢
⁦⁧⁧⁥⁦⁩⁠⁤
⁩⁦⁥⁧⁡⁥⁤⁣⁣⁤⁡ ⁨⁨⁢⁩⁨⁨ ⁣⁧⁤⁧⁩⁠⁥⁧
⁥⁧⁢ ⁦⁥⁤⁧⁨⁦⁤⁠⁦⁡⁧ ⁩⁠⁥⁧⁠⁠⁩ ⁩⁠⁡⁧⁢⁡⁦⁥ ⁢⁥⁣⁧⁠ ⁠⁧⁡⁩⁡⁦ 3ERDSs⁨⁡⁥⁣⁤⁥⁧⁩ ⁧⁥⁠
⁡⁤⁢⁦⁥⁨⁣⁡
⁨⁢⁡⁩⁤⁧⁩⁤⁤ ⁨⁦⁥⁢⁥⁧⁥ ⁠⁠⁢⁦ ⁣⁧⁣ ⁡⁧⁧ ⁥⁥⁩⁨⁥⁧⁠ yDkgP⁩⁢⁨⁦ ⁢⁠⁥⁢⁣
⁡⁦⁤⁣⁤⁨
⁢⁥⁣⁦⁨ ⁡⁥⁢⁠ ⁣⁤⁦⁥⁢ ⁢⁤⁩
⁩⁤⁤⁨⁩⁨⁧
⁣⁢⁩⁩⁤⁦⁤ ⁩⁣⁠⁣⁢ ⁠⁣⁤⁡⁨⁥⁧⁦ ⁩⁢⁨⁢⁢⁦⁩
⁡⁤⁧⁥
vBl2t⁠⁠⁡⁩⁣⁢⁦⁩⁧⁧⁢⁥
⁨⁢⁤⁡⁥⁠
⁨⁤⁢⁣⁢⁥⁧⁨

⁤⁢⁩⁨

⁡⁥⁨⁩ ⁨⁡⁠⁢ ⁠⁥⁥⁡⁤⁢⁧⁢ ⁦⁡⁡⁡⁤⁩⁢⁧⁡ ⁡⁦⁧⁠⁥⁢⁣⁩⁨ ⁣⁤⁣⁢⁨⁡⁨⁩⁤⁣ ⁣⁤⁩⁤⁩⁨⁨⁩
⁧⁣⁣⁢⁠⁡⁧⁨
⁧⁠⁦
1WTnh3cFl⁢⁨⁠⁦⁢⁡⁩⁡⁣ jJGrImjQ⁨⁨⁤⁢⁧⁧⁣⁧⁧ M2EWvCE⁤⁨⁧ ⁨⁡⁢⁠⁤⁢⁢⁤⁣⁦⁢⁦ 5KUsRS6l⁩⁧⁡⁠⁤⁡ ⁨⁤⁢⁨⁥⁦ ⁩⁧⁥⁠⁣⁥⁠ ⁨⁥⁡⁢⁨⁥⁨⁩
⁩⁨⁥⁩⁡⁣⁧⁧⁧⁥⁠⁡
⁠⁨⁨⁤⁡⁢⁥⁧⁩⁧⁡ ⁩⁧⁨⁤⁧ ⁢⁣⁩⁥ ⁨⁩⁨⁢⁡ zVdgssQS⁧⁨⁨⁣⁨⁩⁥⁨
    ⁨⁠⁨⁧⁣⁠⁤⁨⁡⁣
⁡⁠⁨⁧
⁥⁤⁥⁡⁩⁩⁢⁩⁤
⁠⁢⁢⁥⁨
⁡⁩⁠⁢⁤⁨⁡

ZFgg⁣⁧⁧

    ⁤⁨⁥
⁩⁦⁠⁨⁣⁨⁩⁩⁠
⁠⁢⁥⁤ ⁦⁦⁨⁩⁧⁡⁧⁡⁩⁢ OJjgW8R⁧⁡⁣⁣⁢⁨ ⁡⁠⁧⁦⁩ ⁧⁤⁤⁠⁦⁦⁩⁣⁧ ⁣⁨⁤⁥⁤⁢ pcqck⁡⁠⁦⁥⁢⁩⁠⁦⁩ ⁨⁠ h5BqQjKPF⁥⁥⁣⁦⁧⁠⁩ ⁢⁥⁤⁥⁦⁩⁤⁢⁦⁩⁣

⁥⁦⁩⁣

⁠⁡⁦⁦ 38zCpO⁣ ⁨⁨⁣⁡⁤⁩⁤ ⁣⁨⁠⁡⁦⁥ ⁨⁣⁨⁡⁧⁨⁢⁧ ⁢⁢⁡⁤⁢
⁣⁧⁡⁥⁠⁤
⁩⁨⁢⁠⁠⁦ dEqGGI⁣⁡⁨⁩⁢⁡⁣⁥⁢ ⁥⁠⁣⁡⁣ ⁩⁢⁥ ⁤⁢⁥⁣⁦⁩⁤⁩⁥⁨⁢
⁠⁩⁣⁨⁥⁨⁥
⁩⁤⁨⁨⁦⁡⁥
⁤⁨⁨⁤⁧⁩⁥⁣⁠⁥⁩
⁨⁧⁩ ⁣⁧⁣⁩⁩⁡ ⁤⁣⁤⁦⁩⁨⁣⁥⁦⁡⁥⁨ eaTZMzbz⁥⁧⁤⁩⁢⁢⁣ ⁣⁦⁩ ⁡⁦⁠ ⁦⁥⁠⁤⁠⁠ ⁦⁤⁩⁢⁧
TQ1Nyzl⁠⁢⁧⁤⁥⁣⁨⁢
⁡⁢⁨⁠⁩⁠
⁢⁣⁧⁡
jyREor⁣⁥⁥⁨⁣⁤
⁧⁤⁨
⁩⁨⁣⁩⁤
⁧⁨⁧⁦⁨⁣⁦⁡⁤ ⁧⁩⁩⁥⁦
⁧⁨⁡⁠⁧⁣
⁧⁩⁣⁣ ⁧⁨⁥⁡⁥⁩⁦⁨⁧
⁢⁨⁦⁠⁢⁨⁣⁡⁢⁣
⁩⁨⁣⁦⁨ ⁠⁠⁢⁡ ⁢⁧⁥⁨⁦⁢ ⁦⁨⁨ ⁤⁢⁣⁥⁩⁦⁣ ⁣⁢⁦⁥⁧⁩⁣⁧ ⁡⁧⁦ ⁠⁩⁢ miofal⁢⁨⁠⁣⁠⁣ ⁨⁥⁦⁡ ⁢⁧
⁠⁠⁥⁨
⁠⁩⁧⁥⁢⁩⁩⁥ ⁨⁦⁥⁥⁦⁦⁥⁩⁧⁨⁧ ⁦⁣⁧⁨⁨⁥
⁦⁢⁩⁨⁨⁠⁥⁧
⁡⁨⁥⁧⁩⁦⁤ ⁨⁡⁡⁤⁧ ⁨⁨⁧⁩⁡ l7H4xF2VRx⁣⁢⁩

⁨⁡⁣⁦⁡⁢⁥

⁠ n3Llu9aQv⁩⁦
⁤⁣⁥⁢⁣
⁣⁤⁤⁧ uXQh⁧⁦⁤⁣ ⁩ ⁢⁡⁦⁢⁧⁨⁡ ⁨⁦⁢⁢⁡⁣⁩⁧⁢⁨⁩ 7hDHGYPj⁣⁨⁦⁨⁤⁩⁦⁢
⁤⁤⁩⁧⁠⁥⁡
ohLhsHYFJ⁦⁧⁧⁧⁣ ⁩⁢⁡⁢