最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解析從小程序開發(fā)者工具源碼看原理實現(xiàn)

 更新時間:2021年06月09日 15:09:14   作者:lsgxeva  
小程序的架構設計與web技術還是有一定的差別,其吸取了web技術的一些優(yōu)勢,同時也摒棄web技術中體驗等不好的地方。下面通過問題的形式來說說小程序架構中的一些設計點

如何查看小程序開發(fā)者工具源碼

下面我們通過微信小程序開發(fā)者工具的源碼來說說小程序的底層實現(xiàn)原理。以開發(fā)者工具版本號State v1.02.1904090的源碼來窺探小程序的實現(xiàn)思路。如何查看微信源碼,對于mac用戶而言,查看微信小程序開發(fā)者工具的包內容,然后進入Contents/Resources/app.nw/js/core/index.js,注釋掉如下代碼就可以查看開發(fā)者工具渲染后的代碼。

// 打開 inspect 窗口
if (nw.App.argv.indexOf('inspect') !== -1) {
    tools.openInspectWin()
}

然后重啟小程序開發(fā)者工具,就出現(xiàn)如下左側頁面,點擊其中一個頁面就能看到view層的dom結構,如下圖右側。

小程序架構設計

1、小程序渲染是在同一個線程嗎?雙線程機制

開發(fā)過小程序的都知道,小程序是雙線程設計,即視圖渲染與業(yè)務邏輯分別在運行在不同的線程中。這個設計主要是解決web技術中的一個痛點:

web頁面開發(fā)渲染線程和腳本線程是互斥的,長時間的腳本運行可能會導致頁面失去響應或者白屏,體驗糟糕。

小程序為了更好體驗,將頁面的渲染線程和腳本線程分開設計在不同線程中執(zhí)行,具體實現(xiàn):

  • 視圖view層在webview中渲染,一個頁面對應一個webview
  • 業(yè)務邏輯Appservice層運行在同一個JSCore線程中,具體ios是JavaScriptCore,android是X5 JSCore,開發(fā)者工具是webview中;

這樣解決了長時間的腳本阻塞頁面渲染的情況,但是也帶來一些新的問題:

  • 天生的延遲,線程間要通信
  • 業(yè)務邏輯層因為運行在JSCore中無法訪問DOM和BOM的api;

開發(fā)者工具使用webview加載業(yè)務邏輯層的代碼,雖然依賴的環(huán)境有DOM和BOM api,為了保持一致;小程序對所有的模塊進行了局部化處理使其不能訪問這些api。這樣雙線程通過native,開發(fā)者工具通過后臺websocket服務充當二者消息中轉媒介,并且提供一些基礎功能。具體可以參考官網(wǎng)圖:

2、小程序是web渲染嗎?界面渲染機制

頁面渲染的方式主要有三種:

  • 純web渲染
  • 純native原生渲染
  • Hybrid渲染,即web和native渲染結合

因為小程序的宿主環(huán)境是微信,不太可能使用純native渲染,否則所有小程序需要跟微信一起編碼發(fā)版。采用純web渲染貌似是可行的,支持快速在線更新,通過加裝最新資源到本地即可渲染;但是純web渲染在一些有復雜交互的頁面上可能會面臨一些性能問題,這是因為在web技術中,UI渲染跟 JavaScript 的腳本執(zhí)行都在一個單線程中執(zhí)行,這就容易導致一些邏輯任務搶占UI渲染的資源。所以小程序采用Hybrid方式渲染,用官網(wǎng)的描述如下:

界面主要由成熟的 Web 技術渲染,輔之以大量的接口提供豐富的客戶端原生能力。

同時,每個小程序頁面都是用不同的WebView去渲染,這樣可以提供更好的交互體驗,更貼近原生體驗,也避免了單個WebView的任務過于繁重。

既然采用Hybrid方式渲染,那么頁面的渲染可能會用到原生native來渲染,什么情況會用到原生渲染呢?

答案是使用到小程序提供的map、video、canvas、textarea等組件,頁面中原生渲染的渲染原理可以參考官網(wǎng)原生組件。但是在小程序開發(fā)者工具中原生組件是使用html標簽來模擬實現(xiàn)的。具體可以看下一節(jié)的map組件渲染結果。

3、小程序是用web的html標簽渲染嗎?Exparser組件框架

上面說到小程序主要由成熟的web技術渲染,能否直接使用html提供的標簽如div、table等組織頁面呢,答案不可以。主要考量:

  • 管控與安全:web技術可以通過腳本獲取修改頁面敏感內容或者隨意跳轉其它頁面
  • 能力有限,會限制小程序的表現(xiàn)形式
  • 標簽眾多,增加理解成本

所以,小程序不能直接使用html標簽渲染頁面,其提供了10多個內置組件來收斂web標簽,并且提供一個JavaScript沙箱環(huán)境來避免js訪問任何瀏覽器api。

既然小程序不能直接使用html標簽來渲染頁面,那它提供的如view、cover-view等內置組件是否意味著最終都轉換為html提供的內置標簽來渲染呢?答案當不是。我們來看如下代碼:

<view class="map-container">
  <map latitude='39.9088230000' style="height: 100%; width:100%;" longitude='116.3974700000' scale='16' id="id" bindregionchange="onRegionChange"></map>
  <view catchtap="onTap">test</view>
</view>

上面代碼在開發(fā)者工具中最終渲染元素如下圖:

可以看出,小程序提供的組件并沒有最終轉換為為html對應的標簽來渲染,而是使用自定義的元素來渲染。這些內置組件都是由Exparser框架負責管理,它內置在小程序基礎庫中,為小程序的各種組件提供基礎的支持。

Exparser框架基于Shadow DOM模型,模型上與WebComponents的ShadowDOM高度相似,具體可以參考官網(wǎng)組件系統(tǒng)。
內置組件的命名規(guī)范都是以wx-開頭的,外部引用內置組件如view,最終會調用底層的wx-view組件;Exparser的view組件創(chuàng)建方式如下:

4、小程序可以操作dom嗎?數(shù)據(jù)驅動

小程序為了管控與安全,提供一個JavaScript沙箱環(huán)境來運行JavaScript代碼,js代碼不能訪問任何瀏覽器相關的接口,那就意味著js是不能操作dom和bom的,否則可能報錯。小程序實現(xiàn)沙箱環(huán)境呢?即通過將業(yè)務邏輯封裝到一個局部環(huán)境中,局部環(huán)境修改dom和bom的相關api指向。具體封裝形式如下:

那么問題來了,小程序是怎么給業(yè)務代碼加上以上封裝的呢?其實很簡單,在小程序開發(fā)者工具中有一個后臺服務,訪問小程序的每個模塊的path時,后臺服務會調用wrapSourceCodeInDefine方法將請求的JS文件的內容分別包裹在define域中,方法的代碼如下圖所示:

這里的define是小程序底層實現(xiàn)模塊化的方法之一,還有一個是require方法;通過define來定義一個模塊,require來引用一個define定義的模塊。從上面小程序對業(yè)務模塊代碼的封裝可以看出:

define定義的模塊對傳遞了跟瀏覽器相關的接口同名的API,如window、document、localStroage等等
可能有人會說通過Function('return this')()來訪問全局作用域window對象,但是小程序堵死了這條路,重寫了Function,eval重置為undefined。例如下圖:

require在引用模塊時只傳遞require、module、exports三個參數(shù),那么其他參數(shù)值就為undefined,不能在業(yè)務代碼中訪問這些接口

可以看看require定義的源碼:

在實際的微信環(huán)境,業(yè)務邏輯層運行在JSCore中,其沒有瀏覽器相關的信息,訪問dom無從談起;但是小程序開發(fā)者工具使用webview來運行業(yè)務邏輯代碼,它有dom相關接口;所以通過上面沙箱環(huán)境來統(tǒng)一使js無法操作dom。

業(yè)務代碼無法訪問dom,怎么實現(xiàn)頁面動態(tài)更新呢?

答案就是采用類vue這種MVVM框架的數(shù)據(jù)驅動思想,即讓視圖狀態(tài)和視圖綁定在一起,狀態(tài)變更時,視圖也能自動變更,這樣就不用直接操作dom。

視圖的動態(tài)更新具體是采用virtual dom技術實現(xiàn),virtual DOM相信大家都已有了解,大概是這么個過程如下圖:

實際處理可以簡單描述如下:

用JS對象模擬DOM樹 -> 比較兩棵虛擬DOM樹的差異 -> 把差異應用到真正的DOM樹上。

其中,virtual dom是通過內置的wcc可以將wxml轉換為js對象形式,以此來表示DOM樹結構。

下面以官網(wǎng)的一幅圖來說視圖動態(tài)更新的過程:

// wxml
 <view>{{msg}}</view>

// js
data: {
   msg: 'Hello World'
}

上面說明了視圖如何更新的,其實在數(shù)據(jù)響應的過程中,還有最重要的一環(huán),即業(yè)務邏輯層的如何將變化的數(shù)據(jù)同步到視圖層呢,這就涉及到雙線程的通信了

5、小程序基礎庫作用到底是什么?

我們在開發(fā)者工具開發(fā)小程序時,一般都會選擇一個基礎庫,如小程序開發(fā)者工具選擇界面:

小程序基礎庫是用JavaScript寫的,但是我們并沒有在我們的小程序中直接引用,那么我們是怎么使用基礎庫提供功能的呢?答案是:

微信宿主環(huán)境會提前內置基礎庫,打開小程序時會自動將基礎庫注入到小程序的視圖層和業(yè)務邏輯層中,小程序開發(fā)者工具則是由底層HTTP服務負責注入。

下圖是小程序底層HTTP服務通過script腳本注入的相關代碼:

小程序基礎庫功能包括兩個部分視圖層的WAWebview.js和業(yè)務邏輯層的WAService.js。下面就簡單說下對應功能:

WAService為業(yè)務邏輯層提供基礎功能

下看看一下WAService.js源碼內容縮略圖:

從源碼可以看出基礎庫提供的WAService.js有很多功能,主要包括以下幾部分

  • WeixinJSBridge:消息通信的統(tǒng)一封裝易于調用,主要微信環(huán)境與native,開發(fā)環(huán)境與開發(fā)者工具后臺服務的通信。
  • wx: wx對象下面的api方法封裝
  • appServiceEngine:定義了全局的方法如define,require, App,Page,Component,getApp,getCurrentPages等
  • virtualDOM: VirtualDOM,Diff和Render UI實現(xiàn)
  • expraser: expraser框架組件的方法定義,這意味著邏輯層也具有一定的組件樹組織能力。
  • Reporter: 小程序日志組件

WAWebview為視圖層提供基礎功能

小程序基礎庫為視圖層提供的基礎功能有些與WAService相同,主要功能如下:

  • 消息通信封裝為WeixinJSBridge
  • 日志組件Reporter封裝
  • wx對象下的api,跟WAService里的不同的是其大部分都是處理UI顯示相關的方法
  • 小程序Expraser組件框架的實現(xiàn)和內置組件的注冊
  • VirtualDOM,Diff和Render UI實現(xiàn)
  • 定義頁面相關事件觸發(fā)

以上就是解析從小程序開發(fā)者工具源碼看原理實現(xiàn)的詳細內容,更多關于從小程序開發(fā)者工具源碼看原理實現(xiàn)的資料請關注腳本之家其它相關文章!

相關文章

  • JavaScript中EventLoop介紹

    JavaScript中EventLoop介紹

    本篇文章給大家詳細介紹了JavaScript中EventLoop的相關知識,有這方面需要的朋友參考學習下。
    2018-01-01
  • JS 實現(xiàn) ajax 異步瀏覽器兼容問題

    JS 實現(xiàn) ajax 異步瀏覽器兼容問題

    本文通過實例代碼給大家講解了js實現(xiàn)ajax異步瀏覽器兼容問題,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-01-01
  • Js和JQuery獲取鼠標指針坐標的實現(xiàn)代碼分享

    Js和JQuery獲取鼠標指針坐標的實現(xiàn)代碼分享

    這篇文章主要介紹了Js和JQuery獲取鼠標指針坐標的實現(xiàn)代碼分享,本文直接給出實現(xiàn)的代碼,需要的朋友可以參考下
    2015-05-05
  • 利用JS實現(xiàn)簡單的瀑布流加載圖片效果

    利用JS實現(xiàn)簡單的瀑布流加載圖片效果

    今天學習了一個瀑布流加載效果,很多網(wǎng)站都有瀑布流效果,下面通過本文給大家分享利用JS實現(xiàn)簡單的瀑布流加載圖片效果,需要的朋友參考下吧
    2017-04-04
  • 基于JS實現(xiàn)的消消樂游戲的示例代碼

    基于JS實現(xiàn)的消消樂游戲的示例代碼

    這篇文章主要為大家介紹了如何利用JS實現(xiàn)消消樂小游戲,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • js 可選鏈操作符的使用

    js 可選鏈操作符的使用

    可選鏈操作符(?.)允許讀取位于鏈接對象鏈身處的屬性的值,本文就詳細的介紹一下,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 詳解JavaScript是如何驗證URL的

    詳解JavaScript是如何驗證URL的

    當開發(fā)者需要為不同目的以不同形式處理URL時,我們經(jīng)常會借助于JavaScript。本文就為大家整理了JavaScript驗證URL的方法,希望對大家有所幫助
    2023-02-02
  • JavaScript控制網(wǎng)頁層收起和展開效果的方法

    JavaScript控制網(wǎng)頁層收起和展開效果的方法

    這篇文章主要介紹了JavaScript控制網(wǎng)頁層收起和展開效果的方法,涉及javascript操作網(wǎng)頁元素動態(tài)效果的技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • Bootstrap Paginator分頁插件使用方法詳解

    Bootstrap Paginator分頁插件使用方法詳解

    這篇文章主要為大家詳細介紹了Bootstrap Paginator分頁插件使用方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • uni-app的基本使用教程

    uni-app的基本使用教程

    uni-app??? 是一個使用 ???Vue.js?? 開發(fā)所有前端應用的框架,開發(fā)者編寫一套代碼,可發(fā)布到iOS、Android、H5、以及各種小程序(微信/支付寶/百度/頭條/QQ/釘釘)等多個平臺,這篇文章主要介紹了uni-app的基本使用,需要的朋友可以參考下
    2022-11-11

最新評論

灵丘县| 宝丰县| 潜江市| 台南市| 平昌县| 巍山| 措美县| 商水县| 太和县| 吉木乃县| 武胜县| 灵武市| 朝阳区| 丰宁| 哈尔滨市| 伊宁市| 武汉市| 九江市| 清徐县| 永丰县| 大洼县| 西华县| 平凉市| 三穗县| 象山县| 台东县| 鹤岗市| 夏邑县| 临湘市| 彭阳县| 盖州市| 盐城市| 扶风县| 冷水江市| 镇康县| 临沭县| 和龙市| 高安市| 苍梧县| 望谟县| 徐闻县|