自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

微信小程序基礎(chǔ)架構(gòu)淺析

開發(fā) 開發(fā)工具
微信小程序,簡(jiǎn)稱小程序,英文 mini program。是一種不需要下載安裝即可在微信中使用的應(yīng)用,用戶掃描小程序碼或搜索小程序即可打開,觸手可及,用完即走,不用關(guān)心是否安裝太多應(yīng)用的問題。

[[404955]]

 微信小程序,簡(jiǎn)稱小程序,英文 mini program。是一種不需要下載安裝即可在微信中使用的應(yīng)用,用戶掃描小程序碼或搜索小程序即可打開,觸手可及,用完即走,不用關(guān)心是否安裝太多應(yīng)用的問題。

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

內(nèi)部開放微信原生能力

使用 WeixinJSBridge 預(yù)覽圖片

此類 API 最初是提供給騰訊內(nèi)部一些業(yè)務(wù)使用,很多外部開發(fā)者發(fā)現(xiàn)了之后,依葫蘆畫瓢地使用了,逐漸成為微信中網(wǎng)頁(yè)開發(fā)的事實(shí)標(biāo)準(zhǔn)。

JS-SDK 發(fā)布

2015 年初,微信發(fā)布了一整套網(wǎng)頁(yè)開發(fā)工具包,稱之為 JS-SDK,開放了拍攝、錄音、語音識(shí)別、二維碼、地圖、支付、分享、卡券等幾十個(gè) API。讓所有開發(fā)者都可以使用到微信的原生能力。

使用 JS-SDK 調(diào)用圖片預(yù)覽組件

JS-SDK 解決了移動(dòng)網(wǎng)頁(yè)使用微信能力不足的問題,通過暴露微信的接口使得 Web 開發(fā)者能夠擁有更多的能力,然而在更多的能力之外,JS-SDK 的模式并沒有解決使用移動(dòng)網(wǎng)頁(yè)遇到的體驗(yàn)不良的問題。

JS-SDK 的不足

用戶在訪問網(wǎng)頁(yè)的時(shí)候,在瀏覽器開始顯示之前都會(huì)有一個(gè)白屏的過程,在移動(dòng)端,受限于設(shè)備性能和網(wǎng)絡(luò)速度,白屏?xí)用黠@。除了白屏,影響 Web 體驗(yàn)的問題還有缺少操作的反饋,主要表現(xiàn)在兩個(gè)方面:頁(yè)面切換的生硬和點(diǎn)擊的遲滯感。

加載白屏,切換不流暢

此外一些開發(fā)者會(huì)使用 JS-SDK 做一些,比如假紅包,偽造的官方活動(dòng)等。并利用 JS-SDK 的分享能力變相的去裂變分享到各個(gè)群或者朋友圈,由于 JS-SDK 是根據(jù)域名來賦予 api 權(quán)限的,運(yùn)營(yíng)人員封了一個(gè)域名后,他們立馬用別的域名又繼續(xù)做壞,要知道注冊(cè)一個(gè)新的域名的成本是很低的。

那么小程序是通過怎樣的設(shè)計(jì)來改進(jìn) JS-SDK 的體驗(yàn)和管控上的不足?

小程序雙線程架構(gòu)

具體實(shí)現(xiàn)上小程序采用了類 web + 離線包的形式。開發(fā)上與 web 類似,門檻較低,開發(fā)效率較高。離線下載和頁(yè)面預(yù)渲染功能增強(qiáng)了用戶體驗(yàn),提升了加載速度,解決了 JS-SDK 加載白屏的問題 1。小程序提供了云端更新離線包的功能,可動(dòng)態(tài)更新頁(yè)面,相對(duì)于 app 的更新和發(fā)布更為靈活。此外,小程序在離線包的基礎(chǔ)上對(duì)切換動(dòng)畫進(jìn)行優(yōu)化,降低了切換頁(yè)面導(dǎo)致的遲滯感,緩解了切換不流暢的問題 2。

小程序web+離線包模式

小程序在架構(gòu)方面最大的特點(diǎn)是采用了雙線程的開發(fā)模式,隔離了 JS 邏輯和 UI 渲染。小程序的渲染層和邏輯層分別由 2 個(gè)線程管理:渲染層的界面使用了 WebView 進(jìn)行渲染,邏輯層采用 JsCore 線程運(yùn)行 JS 腳本。

邏輯層:創(chuàng)建一個(gè)單獨(dú)的線程去執(zhí)行 JavaScript,在這個(gè)環(huán)境下執(zhí)行的都是有關(guān)小程序業(yè)務(wù)邏輯的代碼;

渲染層:界面渲染相關(guān)的任務(wù)全都在 WebView 線程里執(zhí)行,通過邏輯層代碼去控制渲染哪些界面。一個(gè)小程序存在多個(gè)界面,所以渲染層存在多個(gè) WebView 線程;

通信:這兩個(gè)線程的通信會(huì)經(jīng)由微信客戶端(下文中也會(huì)采用 Native 來代指微信客戶端)做中轉(zhuǎn),邏輯層發(fā)送網(wǎng)絡(luò)請(qǐng)求也經(jīng)由 Native 轉(zhuǎn)發(fā),小程序的通信模型下圖所示。

小程序雙線程架構(gòu)

JS 邏輯層運(yùn)行在 JSCore 中,并沒有一個(gè)完整瀏覽器對(duì)象,因而缺少相關(guān)的 DOM API 和 BOM API,無法操作頁(yè)面元素,能達(dá)到管控的目的,但也限制了開發(fā)者的權(quán)限:

  • 不允許開發(fā)者把頁(yè)面跳轉(zhuǎn)到其他在線網(wǎng)頁(yè)
  • 不允許開發(fā)者直接訪問 DOM
  • 不允許開發(fā)者隨意使用 window 上的某些未知的可能有危險(xiǎn)的 API

這樣的邏輯層與 UI 層的隔離,加上小程序的審核和舉報(bào)機(jī)制,使得微信加強(qiáng)對(duì)小程序的管控,解決了問題 3。但這也使得開發(fā)者無法靈活的進(jìn)行頁(yè)面渲染。

小程序頁(yè)面渲染

上面已經(jīng)說了邏輯層無法操作 DOM 變更,那小程序是如何進(jìn)行頁(yè)面的渲染呢?小程序基于數(shù)據(jù)驅(qū)動(dòng)的架構(gòu)模式,基于 Virtual Dom(React 引入,真實(shí) DOM 的一種 JS 描述方式)的概念,業(yè)務(wù)側(cè)只需要改變數(shù)據(jù)即可引起界面變化。其中渲染層提供了帶有數(shù)據(jù)綁定語法的 WXML,邏輯層提供了setData 等等 API,開發(fā)者需要進(jìn)行界面變化時(shí),只需要通過在邏輯層執(zhí)行 setData 把變化的數(shù)據(jù)通過 Native 層傳遞到渲染層,小程序會(huì)進(jìn)行 Dom Diff(DOM 結(jié)構(gòu)對(duì)比并進(jìn)行最小化變更的算法)等流程,最后把正確的結(jié)果更新在 Dom 樹上。

小程序Virtual DOM渲染

完整的通信流程大致如下:

  1. 邏輯層調(diào)用宿主環(huán)境的 setData 方法。
  2. 邏輯層將待傳輸數(shù)據(jù)轉(zhuǎn)換成字符串,并拼接到特定的 JS 腳本,最后將數(shù)據(jù)傳輸?shù)戒秩緦印?/li>
  3. 渲染層接收到后,WebView JS 線程會(huì)對(duì)腳本進(jìn)行編譯,得到待更新數(shù)據(jù)后進(jìn)入渲染隊(duì)列,等待 WebView 線程空閑時(shí)進(jìn)行頁(yè)面渲染。
  4. WebView 線程開始執(zhí)行渲染時(shí),待更新數(shù)據(jù)會(huì)合并到視圖層保留的原始 data 數(shù)據(jù),并將新數(shù)據(jù)套用在 WXML 片段中得到新的虛擬節(jié)點(diǎn)樹。經(jīng)過新虛擬節(jié)點(diǎn)樹與當(dāng)前節(jié)點(diǎn)樹的 diff 對(duì)比,將差異部分更新到 UI 視圖。同時(shí)將新的節(jié)點(diǎn)樹替換舊節(jié)點(diǎn)樹,用于下一次重渲染。

小程序方案與 React Native 對(duì)比

那么小程序與現(xiàn)有的混合開發(fā)技術(shù)類型的異同點(diǎn)在哪?尤其是與 React Native 的區(qū)別,小程序技術(shù)架構(gòu)為什么沒有使用 React Native?

混合開發(fā)技術(shù)類型

現(xiàn)有的混合開發(fā)類型,基于 UI 渲染的分類來看,主要有兩類:

  1. 基于 WebView UI 的基礎(chǔ)方案。市面上主流,例如微信 JS-SDK,通過 JSBridge 完成 H5 和 Native 的雙向通訊,從而賦予 H5 一定的原生能力。
  2. 基于 Native UI 的方案,例如 React-Native、Weex、Flutter 等。在賦予 H5 原生 API 能力的基礎(chǔ)上,進(jìn)一步通過 JSBridge 將 JS 解析成虛擬 DOM 傳遞到 Native,并使用原生渲染。

小程序也屬于類型 1,本次我們主要以類型 2 中的 React Native 作為對(duì)比分析。

React Native 技術(shù)架構(gòu)

框架

React Native 框架主要有三層:

  • JS 層:該層提供了各種供開發(fā)者使用的組件以及一些工具庫(kù)(事件分發(fā)等)。
  • C++層:主要處理 java/OC 與 JS 的通信(JSBridge)以及執(zhí)行 JavaScript(JS 腳本引擎)。
  • Native 層(Object C/Java 層):主要包括 UI 渲染器、網(wǎng)絡(luò)通信等工具庫(kù)。根據(jù)不同操作系統(tǒng)有不同的實(shí)現(xiàn)。

UI 渲染

React Native 基于 react 框架(Virtual Dom)來進(jìn)行 UI 渲染,具體的流程大致如下:

  1. 首先 JS 層通過 JSX 編寫的 Virtual Dom 來構(gòu)建 Component
  2. Native 層將其轉(zhuǎn)成真實(shí) DOM 插入到原生 App 的頁(yè)面中。
  3. 當(dāng)有變更,通過 diff 算法生成差異對(duì)象
  4. 最終由 Native 層將差異對(duì)象應(yīng)用到原生 App 的頁(yè)面元素上。

通信

React Native 基于 JSCore 實(shí)現(xiàn) js 與 java/oc 交互,具體流程大致如下:

  1. 把 JSX 代碼解析成 javaScript 代碼
  2. 讀取 JS 文件,并利用利用 JS 腳本引擎執(zhí)行
  3. 返回一個(gè)數(shù)組,數(shù)組中會(huì)描述 OC/Java 對(duì)象,描述對(duì)象屬性和所需要執(zhí)行的方法,這樣就能讓這個(gè)對(duì)象設(shè)置屬性,并且調(diào)用方法。

Reactive Native架構(gòu)

React Native 優(yōu)缺點(diǎn)

優(yōu)勢(shì)

  • 原生渲染,性能更好,用戶體驗(yàn)較好;
  • React 生態(tài)較好,對(duì)前端開發(fā)友好;
  • hybrid 技術(shù)跨平臺(tái)開發(fā),成本及難度低于原生;
  • 可熱更新,能夠方便迭代。

劣勢(shì)

  • 支持的樣式是 CSS 的子集,會(huì)滿足不了 Web 開發(fā)者日漸增長(zhǎng)的需求;
  • 現(xiàn)有能力下還存在的一些不穩(wěn)定問題,比如性能、Bug 等;
  • 把渲染工作全都交由客戶端原生渲染,會(huì)有更接近原生的體驗(yàn),但實(shí)際上一些簡(jiǎn)單的界面元素使用 Web 技術(shù)渲染完全能勝任;
  • React Native 之前爆出了一個(gè)開源協(xié)議問題(Facebook BSD+Patents ,大致內(nèi)容是使用基于 Facebook BSD+Patents 協(xié)議的開源項(xiàng)目的開發(fā)者,未來要是因?yàn)閷@麊栴}與 Facebook 產(chǎn)生糾紛,那么 Facebook 將有權(quán)停止你使用該開源項(xiàng)目),這對(duì)于之后也是存在隱患的。

小程序不選擇 React Native 原因

據(jù)小程序開發(fā)人員告知的原因如下:

  • React Native 只支持 CSS 的子集,作為一個(gè)開放的生態(tài),需要告知開發(fā)者哪些 CSS 屬性能用,哪些不能用,這樣的開發(fā)體驗(yàn)較差;(對(duì)應(yīng)上面的劣勢(shì) 1)
  • React Native 本身存在一些問題,這些依賴 RN 的修復(fù),同時(shí)這樣就變成太過依賴客戶端發(fā)版本去解決開發(fā)者那邊的 Bug,修復(fù)周期太長(zhǎng)。(對(duì)應(yīng)上面的劣勢(shì) 2)
  • React Native 前陣子還搞出了一個(gè)開源協(xié)議問題,來說也是存在隱患的。(對(duì)應(yīng)上面的劣勢(shì) 4)

小程序與 React Native 相同點(diǎn)

  • 都具有 hybrid 技術(shù)的優(yōu)點(diǎn):接近原生的體驗(yàn),跨平臺(tái)開發(fā)
  • 使用 Web 相關(guān)技術(shù)框架來編寫業(yè)務(wù)代碼,React Native 為 React 框架,小程序?yàn)樾〕绦蜷_發(fā)框架。
  • 各自實(shí)現(xiàn)了跨語言通訊方案完成 Native(Java/Objective-c/…)端與 JavaScript(小程序中為渲染層和邏輯層)的通訊

小程序與 React Native 不同點(diǎn)

小程序使用瀏覽器內(nèi)核 WebView 來渲染界面(小部分原生組件由客戶端參與渲染),界面主要由成熟的 Web 技術(shù)渲染,輔之大量的接口提供豐富的客戶端原生能力,而 React Native 是客戶端原生渲染。理論上 React Native 相對(duì)于 WebView 的性能更好,但小程序的類 web 開發(fā)對(duì)開發(fā)來說入門相對(duì)簡(jiǎn)單,像是一種開發(fā)效率與性能的雙刃劍。

小程序開發(fā)注意事項(xiàng)

基于上面的架構(gòu)分析,我們?cè)陂_發(fā)中需要注意是:

  1. 避免使用操作操作 DOM 的 npm 包。由于邏輯層和渲染層隔離,邏輯層無法操作 DOM/BOM API,所以需要使用 DOM/BOM API 相關(guān)的 npm 包和庫(kù)中不可使用。
  2. 避免頻繁調(diào)用setData。由于setData中的數(shù)據(jù)不僅需要通過 Native 層傳遞到渲染層,通過 DOM diff 算法等渲染成最終頁(yè)面,所以需要盡量減少setData的使用以避免性能問題。
  3. 避免setData傳遞大量的新數(shù)據(jù)。數(shù)據(jù)的傳輸會(huì)經(jīng)歷跨線程傳輸和腳本編譯的過程,當(dāng)數(shù)據(jù)量過大,會(huì)增加腳本編譯的執(zhí)行時(shí)間,占用 WebView JS 線程,從而影響到最終的渲染性能。

 

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2017-06-09 10:06:54

微信小程序架構(gòu)分析

2017-06-09 12:58:20

微信小程序架構(gòu)分析

2017-06-09 10:40:00

微信小程序架構(gòu)分析

2017-05-08 15:03:07

微信小程序開發(fā)實(shí)戰(zhàn)

2016-11-04 10:47:27

微信小程序

2016-10-20 21:02:12

微信小程序javascript

2017-01-09 10:01:49

微信小程序

2016-11-04 10:31:49

微信程序指南

2016-09-28 18:10:59

微信程序MINA

2016-11-22 11:23:52

微信小程序騰訊微信

2016-09-27 16:38:24

JavaScript微信Web

2016-09-27 15:40:58

微信程序前端

2016-11-04 10:49:48

微信小程序

2016-11-19 18:06:44

微信小程序張小龍

2016-09-27 20:36:23

微信HttpWeb

2017-06-27 10:53:32

2017-02-06 13:32:12

微信小程序思想

2018-07-26 15:16:50

小程序iPhone X甜酸

2018-09-11 10:32:07

云開發(fā)小程序開發(fā)者

2016-11-04 09:55:16

微信小程序
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)