亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

微信小程序包含下面四種文件:

  • js
  • json 配置文件
  • wxml 小程序?qū)S?xml 文件
  • wxss 小程序?qū)S?css 文件
<view>
 <text class="window">{{ text }}</text>
</view> 
Page({
 data:{
 text:"這是一個頁面"
 },
 onLoad:function(options){
 // 頁面初始化 options為頁面跳轉(zhuǎn)所帶來的參數(shù)
 },
 // ........
}) 

微信小程序只能通過其 mvvm 的模板語法來動態(tài)改變頁面,本身 js 并不支持 BOM 和 DOM 操作。

從開發(fā)工具看微信小程序架構(gòu)

在 mac 端直接解壓應(yīng)用 發(fā)現(xiàn) App.nw 文件夾,即開發(fā)工具源碼。可以知道該項(xiàng)目由 nw.js 編寫; 在 package.json 文件下找到應(yīng)用入口:app/html/index.html。入口 js 為 dist/app.js 我們可以看到整個編輯器的大致邏輯。

但我們關(guān)心的是構(gòu)建過程,在 weapp 文件夾下存在 build.js 文件。沒有找到有用的信息,只看到了 upload 模塊,包括對大小限制,上傳包命名。

為此懷疑,微信小程序本身和 RN 類似。是在服務(wù)端打包成 native 語言的。但是通過 Android 邊框測試發(fā)現(xiàn),微信小程序根本不是 native 原生內(nèi)容。

原生界面效果:

微信小程序架構(gòu)原理

 

編譯過程

繼續(xù)在 trans 文件夾下發(fā)現(xiàn)了編譯模板。

  • transWxmlToJs wxml 轉(zhuǎn) js
  • transWxssToCss wxss 轉(zhuǎn) css
  • transConfigToPf 模板頁配置
  • transWxmlToHtml wxml 轉(zhuǎn) html
  • transManager 管理器

用到的內(nèi)容:

  • 發(fā)現(xiàn)用到了一個模板:app.nw/app/dist/weapp/tpl/pageFrameTpl.js, app.mw/app.dist.weapp/tpl/appserviceTpl.js
  • wcc 可執(zhí)行程序,wcc 用于轉(zhuǎn)轉(zhuǎn) wxml 中的自定義 tag 為 virtual_dom
  • wcsc 可執(zhí)行程序,用于將 wxss 轉(zhuǎn)為 view 模塊使用的 css 代碼,使用方式為 wcsc xxx.wxss

在模板中,我們發(fā)現(xiàn)使用了 WAWebview.js 文件,WAService.js文件。 在 transWxmlToJs 中我們發(fā)現(xiàn)一段 generateFuncReady 事件的函數(shù)。對比注冊該事件的函數(shù)在 WAWebview.js 中。

我們嘗試使用 wcc 對input.xml 文件進(jìn)行編譯。

wcc -d input.xml

生成了一段腳本:

window.__wcc_version__ = 'v0.6vv_20161230_fbi'
var $gwxc
var $gaic = 
$gwx = function (path, global) {
 function _(a, b) {
 b && a.children.push(b);
 }
 ....

通過代碼我們發(fā)現(xiàn),調(diào)用 $gwx 函數(shù)會再生成一個有返回值的函數(shù)(前提是 path 填寫正確);于是我們執(zhí)行如下代碼:

$gwx("input.xml")("test")

得出如下內(nèi)容:

{
 "tag": "wx-page",
 "children": [
 {
 "tag": "wx-view",
 "attr": {
 "class": "section"
 },
 "children": [
 {
 "tag": "wx-input",
 "attr": {
 "autoFocus": true,
 "placeholder": "這是一個可以自動聚焦的input"
 },
 "children": []
 }
 ]
 }
 ]
} 

這應(yīng)該是一個類似 Virtual dom 的對象,交給了 WAWebivew.js 來渲染,標(biāo)簽名為 wx-view, wx-input。

WAWebview.js

  1. 代碼在最一開始提供的是兼容性工具,還有一個 WeixinJSBridge 引入。
  2. 接下來是一個 Reporter 對象,它的作用就是發(fā)送錯誤和性能統(tǒng)計數(shù)據(jù)給后臺。
微信小程序架構(gòu)原理

 

  1. wx 核心對象,包含了 wx 對象下的 api。但是這里的 api 數(shù)量遠(yuǎn)遠(yuǎn)少于官方的 api 文檔數(shù)量。
微信小程序架構(gòu)原理

 

我們可以在代碼里面發(fā)現(xiàn),wx 下注冊的 api 最終都會調(diào)用 WeixinJSBridge 方法。這個方法應(yīng)該是在打包的時候端上注入的。我們也可以在 WAServeice.js 中找到該方法的定義。

微信小程序架構(gòu)原理

 

所以我們得到了一個結(jié)論,WAService.js 是編輯器用來接受 wx 方法回調(diào)的代碼。

  1. wxparser 對象,提供 dom 到 wx element 對象之間的映射操作,提供元素操作管理和事件管理功能。
  2. 之后代碼是對 exparser 對象的處理,包括注冊 WeixinJSBridge 全局事件,Virtual dom 算法實(shí)現(xiàn),樣式注入等。介紹幾個組件重要的內(nèi)容
  • exparser.registerBehavior 注冊組件基礎(chǔ)行為,供組件繼承。
微信小程序架構(gòu)原理

 

  • exparser.registerElement 為各種內(nèi)置組件,注冊模板,行為,屬性,監(jiān)聽器等內(nèi)容
微信小程序架構(gòu)原理

 

這里我們觀察到,組件:wx-video, wx-canvas, wx-contact-button, wx-map, wx-textarea 等 behaviors 都含有 "wx-native" 屬性。這是不是意味著,這類組件都是 native 原生實(shí)現(xiàn)的呢。我們打開邊框檢查,發(fā)現(xiàn)這類組件確實(shí)都是原生的組件。

微信小程序架構(gòu)原理

 

綜上,微信小程序的界面有部分組件使用原生方式實(shí)現(xiàn)的,native 組件層在 WebView 層之上。大部分還是用前端實(shí)現(xiàn)的,這樣解釋了微信小程序的一個bug。

微信官方文檔:

微信小程序架構(gòu)原理

 

 

因?yàn)?20scroll-view%20是前端實(shí)現(xiàn),在里面使用%20native%20組件,這樣就無法監(jiān)聽滾動了。

WeixinJSBridge

組件是需要數(shù)據(jù)來渲染的,查看文檔我們知道發(fā)送請求的%20api%20為%20wx.request;通過上面分析,我們知道%20wx.request%20實(shí)際調(diào)用的是%20WeixinJSBridge。現(xiàn)在我們看看%20WeixinJSBridge

 

WeixinJSBridge 真正發(fā)送處理數(shù)據(jù)請求的是這段代碼;如果當(dāng)前環(huán)境是 IOS, 那么調(diào)用 WKWebview 的 window.webkit.messageHandlers.invokeHandler.postMessage。如果所處環(huán)境是 android 則調(diào)用 WeixinJSCore.invokeHandler (調(diào)用的時候,默認(rèn)會帶上當(dāng)前 webviewID)。

WAService.js

在對 WeixinJSBridge.js 分析中,我們并沒有發(fā)現(xiàn)前端的通訊功能,路由能力,數(shù)據(jù)綁定等內(nèi)容。進(jìn)一步查看找到了一個 WAService.js 文件。 查看 WAService.js 文件源碼:

  1. 在代碼最開始,跟 WAWebview.js 一樣的 WeixinJSBridge 兼容模塊
  2. 然后是跟 WAWebview.js 一樣的 Reporter 模塊。
  3. 比 WAWebview.js 中 wx 功能更為豐富 wx 接口模塊。(剩余部分 wx api 都在這里)
  4. appServiceEngine 模塊,提供 Page,App,GetApp 接口
  5. 為 window 對象添加 AMD 接口 require define

綜上,WAService.js 主要實(shí)現(xiàn)的功能:

  • App( ) 小程序的入口;Page( ) 頁面的入口
  • wx API;
  • 頁面有的作用域,提供模塊化能力
  • 數(shù)據(jù)綁定、事件分發(fā)、生命周期管理、路由管理

到這里我們得出結(jié)論,小程序的架構(gòu)方案:

微信小程序架構(gòu)原理

 

整個小程序由兩個 webview 組成,代碼分為 UI 層和邏輯層。UI 層運(yùn)行在第一個 WebView 當(dāng)中,執(zhí)行 DOM 操作和交互事件的響應(yīng),里面是 WAWebview.js 代碼及編譯后的內(nèi)容。邏輯層執(zhí)行在(第二個webview 中)獨(dú)立的 JS 引擎中(iOS:JAVAScriptCore, android:X5 JS解析器;統(tǒng)稱 JSCore;開發(fā)工具中,nwjs Chrome 內(nèi)核),WAService.js 代碼和業(yè)務(wù)邏輯。

當(dāng)我們對 view 層進(jìn)行事件操作后,會通過 WeixinJSBridge 將數(shù)據(jù)傳遞到 Native 系統(tǒng)層。Native 系統(tǒng)層決定是否要用 native 處理,然后丟給 邏輯層進(jìn)行用戶的邏輯代碼處理。邏輯層處理完畢后會將數(shù)據(jù)通過 WeixinJSBridge 返給 View 層。View 渲染更新視圖。

架構(gòu)的討論

微信的這種架構(gòu),對邏輯和UI進(jìn)行了完全隔離,小程序邏輯和UI完全運(yùn)行在2個獨(dú)立的Webview里面來處理。那么這么做的好處是啥?總感覺更加麻煩了。除了小程序外,還有人采用這種架構(gòu)設(shè)計么?

在網(wǎng)上搜索了一下,目前使用這種架構(gòu)的項(xiàng)目還真有一個:去哪兒最新的 YIS 框架

YIS 采取了類似小程序的架構(gòu),分為邏輯層和UI層。UI 層運(yùn)行在 WebView 中,而邏輯層運(yùn)行在獨(dú)立的 JS 引擎中。相應(yīng)地,整個應(yīng)用的代碼,也分為兩個大的部分,一部分運(yùn)行在 WebView 中,一部分運(yùn)行在JS引擎中。JS引擎計算DOM結(jié)構(gòu)輸出給WebView,WebView轉(zhuǎn)發(fā)用戶的點(diǎn)擊事件給JS引擎。

該項(xiàng)目做法和小程序十分類似,唯一缺少的就是沒有 native 的組件吧。然而官方文檔上也沒有任何介紹,為什么要這么做,只是說更流暢了。

一些看法

傳統(tǒng) web 頁面顯示需要經(jīng)歷一下幾個步驟:

  1. webview 初始化
  2. 加載 HTML, CSS, JS
  3. 編譯 JS
  4. Render 計算
  5. DOM Path

而利用小程序架構(gòu)后,我們就可以將上述過程拆解成兩部分并行執(zhí)行: webview 部分:

  1. webview 初始化
  2. 加載 HTML,CSS, JS (經(jīng)過拆分后,體積大幅度減小)
  3. 編譯 JS
  4. 等待頁面需要的數(shù)據(jù)
  5. 反序列化數(shù)據(jù)
  6. 執(zhí)行 Patch
  7. 渲染頁面
  8. 等待更多消息

jscore 部分:

  1. 初始化
  2. 加載框架 js 代碼
  3. 編譯 js
  4. 加載業(yè)務(wù)邏輯 js 代碼
  5. 編譯 js
  6. 計算首屏虛擬 DOM 結(jié)構(gòu)
  7. 序列化數(shù)據(jù),傳輸
  8. 等待 webview 消息,或者 Native 消息

這樣渲染進(jìn)程和邏輯進(jìn)程分離,并行處理:加速首屏渲染速度;避免單線程模型下,js 運(yùn)算時間過長,UI 出現(xiàn)卡頓。 完全采用數(shù)據(jù)驅(qū)動的方式,不能直接操作 DOM,利用定制開發(fā)規(guī)范的方式避免低質(zhì)量的代碼的出現(xiàn)。

當(dāng)然這種架構(gòu)方案也有一定的缺點(diǎn):

  1. 不能靈活操作 DOM,無法實(shí)現(xiàn)較為復(fù)雜的效果
  2. 部分和 NA 相關(guān)的視圖有使用限制,如微信的 scrollView 內(nèi)不能有 textarea。
  3. 頁面大小、打開頁面數(shù)量都受到限制
  4. 需要單獨(dú)開發(fā)適配,不能復(fù)用現(xiàn)有代碼資源。
  5. 在 jscore 中JS 體積比較大的情況下,其初始化時間會產(chǎn)生影響。
  6. 傳輸數(shù)據(jù)中,序列化和反序列化耗時需要考慮

希望本文能幫助到您!

點(diǎn)贊+轉(zhuǎn)發(fā),讓更多的人也能看到這篇內(nèi)容(收藏不點(diǎn)贊,都是耍流氓-_-)

關(guān)注 {我},享受文章首發(fā)體驗(yàn)!

每周重點(diǎn)攻克一個前端技術(shù)難點(diǎn)。更多精彩前端內(nèi)容私信 我 回復(fù)“教程”

原文鏈接:http://eux.baidu.com/blog/fe/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86

作者:田光宇

分享到:
標(biāo)簽:程序 微信小
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定