對無線電商動態化方案的思考(二)
上一篇談到了我對無線電商動態化的理解,並簡單提到了我們自己提出的技術方案:Weex,今天就來詳細介紹一下 Weex
一句話介紹
Weex 是一款輕量級的移動端跨平臺動態性技術解決方案!
幾個特點
輕量
體積小巧,語法簡單,方便上手
可擴充套件
業務方可自行橫向定製 native 元件和 API
高效能
快速載入,快速渲染,體驗流暢
其它
- 擁抱標準:基於 Web 標準設計語法
- 響應式介面: 通過簡單的模板和資料繫結輕鬆解決資料和檢視的同步關聯問題
- 多端統一:iOS、Android、HTML5 多端效果一致,撰寫一次就可以輕鬆達到跨平臺的一致性,無需針對多套平臺單獨開發,省時省力
- 複雜邏輯描述:動態性不只體現在展示效果的動態性上,更體現在可以實時調整複雜的資料處理方式和邏輯控制方式
- 元件化:元件之間通過 webcomponents 的設計完美的隔離,並可以通過特定的方式進行資料和事件的傳遞
- 生態&鏈路:我們為 Weex 的開發者和使用者在不同維度上提供了各式各樣的工具和平臺,包括程式碼打包工具、開發者除錯工具、部署平臺、Playground、經典案例、入門指南和詳盡的文件等。你不是從零開始,你也不是一個人在戰鬥!
如何工作
1. 本地元件開發
首先,我們像開發 webcomponents 一樣,把一個元件分成 <template>
、<style>
、<script>
三部分,剛好對應一個元件的介面結構、介面樣式、資料&邏輯。
細節1:順便說一句,這也是我們認為描述介面的最佳實踐。
程式碼示例:
<template>
<container style="flex-direction: column;">
<container repeat="{{itemList}}" onclick="gotoDetail">
<image class="thumb" src="{{pictureUrl}}"></image>
<text class="title">{{title}}</text>
</container>
</container>
</template>
<style>
.thumb {width: 200; height: 200;}
.title {flex: 1; color: #ff0000; font-size: 48; font-weight: bold; background-color: #eeeeee;}
</style>
<script>
module.exports = {
data: {
itemList: [
{itemId: `520421163634`, title: `寶貝標題1`, pictureUrl: `https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg`},
{itemId: `522076777462`, title: `寶貝標題2`, pictureUrl: `https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg`}
]
},
methods: {
gotoDetail: function () {
this.$openURL(`https://item.taobao.com/item.htm?id=` + this.itemId)
}
}
}
</script>
顯然這些程式碼是不會被 native app 識別的,我們要想辦法讓這些程式碼可執行。所以我們同時做了三件事:
- 在本地用一個叫做 transformer 的工具把這套程式碼轉成純 JavaScript 程式碼
- 在客戶端執行一個 JavaScript 引擎,隨時接收 JavaScript 程式碼
- 在客戶端設計一套 JS Bridge,讓 native 程式碼可以和 JavaScript 引擎相互通訊
所以緊接著第二步,就是用 transformer 對程式碼進行轉換,變成客戶端可執行的 JavaScript 程式碼
其實本地開發還有一點很重要,就是把複雜的介面通過元件化的方式進行分解,併合理的建立元件之間的組合和呼叫關係。
最終,我們把簡單元件組合成複雜的介面,並通過 transformer 打包成一個完整的程式包 (主體是一段 JavaScript 程式碼)
細節2:由於 Weex 元件的開發和 Web 元件的開發非常接近,但是對標準的支援範圍和一些細節是有不同之處的,我們會貼心的在 transformer 里加入了一些友情提醒,幫助大家迴避常犯的書寫錯誤。
2. 客戶端渲染
上一節已經提到了,我們在客戶端會執行一個 JavaScript 引擎並且有 JS Bridge 通訊機制。這裡再介紹具體一些:
native 渲染和 JavaScript 引擎之間,主要進行三類通訊:
- 介面渲染,單向 (JS -> native):這毫無疑問,JavaScript 引擎需要把介面的結構和樣式告訴 native 端,這樣我們才能得到 native 級別的終極介面效果
- 事件繫結與觸發,雙向:在我們的客戶端技術方案中,native 端只負責介面渲染和非常薄的事件觸發層,事件的邏輯處理都會放在 JavaScript,這樣我們就具備了複雜資料處理和邏輯控制的動態性可能。JS 告訴 native 需要監聽的互動行為,而當使用者產生對應的互動行為時,native 端會把互動資訊回傳給 JS
- 對外的資料/資訊請求與響應,雙向:JS 引擎在處理特殊邏輯時,難免需要向伺服器請求資料、或請求本地的系統資訊和使用者資訊、或呼叫 native 的某個功能,這個時候也會通過 JS Bridge 進行請求,native 收到這些請求之後,也會在必要的情況下通過 JS Bridge 把資訊回傳給 JS 引擎
再加上外層對 Weex 例項的管理,整套機制就可以順暢的工作起來了
細節3:native 端渲染的時候,我們以圖片和文字的形態為主,並大量依賴了標準的 CSS 樣式進行細節的渲染
細節4:我們把框架層面的 JS 程式碼全部提前放在了客戶端本地,並提前執行做好準備。這樣本地生產的 JavaScript 是非常小的,網路傳輸的代價也非常低,而在客戶端執行的初始化成本也非常低。整條鏈路都和介面開啟速度息息相關
細節5:我們在 JS 處理介面邏輯的過程中採取了資料監聽+依賴收集的策略,既沒有通過髒檢查,也沒有通過全量 diff Virtual DOM 樹的方式,因為通常在移動端,資料變更都是非常小量的,經過我們的實踐,這套方案完全可以應付移動端日常的動態性介面需求
細節6:我們對業務上通用常用的元件進行了封裝,並且暴露規範化的型別 (標籤名)、特性、樣式、事件、上下級約束等維度的定義。這樣所有的業務介面都可以用這些基礎的元件搭建而成
細節7:我們對業務上通用常用的 API 進行了封裝,並且暴露規範化的 JS API
3. 服務端部署
我們在服務端提供了基礎的程式包釋出,給每個程式包一個特定的 page id,然後為客戶端提供通用的服務,通過 page id 獲取程式包,這樣本地開發、動態實時部署、客戶端動態化渲染和邏輯處理就完美的串聯在一起了
細節8:實際上,除了介面本身可以動態化之外,客戶端的 JS 引擎的程式碼、還有部分 native 的實現,我們也準備了相應的動態化機制,也就是說客戶端的動態能力本身也是具有動態性的
4. 瀏覽器端渲染
我們還會面對這樣的場景,就是一個客戶端的業務,會通過微博之類的渠道進行轉播和推廣,當使用者手機裡剛好安裝了手機淘寶客戶端,那麼會直接“拉起”客戶端進行相應的介面展示,如果沒有裝手機淘寶,則需要在瀏覽器裡展示一個相同或接近的介面。自然 Weex 技術方案支援的業務也有這樣的需求。所以我們同時提供了 HTML5 版本的技術方案,同一份 JavaScript 程式包,可以同時通過客戶端的 JS Bridge 渲染成為 native 介面,也可以通過瀏覽器渲染成為 web 介面。我們的做法也非常簡單,就是把 JS Bridge 背後的 native 處理邏輯同構成了 HTML5 版本。然後釋出這樣的一個頁面。
細節9:我們能夠同構 HTML5 版本和 native 版本,主要歸功於我們在 JS Bridge、元件定義、API 定義方面的高度抽象——當然 HTML5 的版本在效能和體驗上確實有一定的劣勢,並不是最理想化的效果,所以核心的主戰場還是客戶端,這也和目前的移動網際網路的形態相吻合
綜上所述,整個 Weex 的工作原理大致可以用一張圖來表述:
回看 Weex 的幾個特點
輕量
我們致力於把開發體驗、網路傳輸的大小、執行時的開銷控制做到極致,並且儘可能的降低多端適配和優雅降級的成本
橫向可擴充套件
我們對元件的定義和業務功能預留了很好的橫向可擴充套件能力,這也業務方可以自由定製屬於自己的 native 元件和 API,從而在後期可以通過實時釋出不同的程式包來進行動態化控制。同時也因為它的橫向可擴充套件性,Weex 的核心可以非常小,非常易於融入現有的無線技術體系
高效能
我們在網路傳輸、例項初始化、JS 運算、native 渲染能力等方面做了非常針對性且深入的優化,尤其是針對中低端安卓機,不論是載入時間還是執行時的流暢度,都比之前的方案有質的飛躍。我們對 CPU、記憶體、幀率、首屏渲染時間等核心效能指標也一直保持高度的關注,也建立了相應的線上監控和資料統計機制。而更多可優化的空間和方案我們還在不斷的進行優化嘗試。
下圖是今天凌晨舊金山 QCon 上 Weex 技術方案的首次公開分享中的一頁效能表現對比圖,大家可以感受一下:
總結
這就是 Weex,如上一篇文章所介紹的:
- 致力於移動端
- 能夠充分排程 native 的能力
- 能夠充分解決和迴避效能瓶頸
- 能夠靈活擴充套件
- 能夠多端統一
- 能夠優雅“降級”到 HTML5
- 能夠保持較低的開發成本
- 能夠快速迭代
- 能夠輕量實時釋出
- 能夠融入現有的 native 技術體系
- 能夠工程化管理和監控
目前 Weex 還在努力達到更高的效能、更高的擴充套件性、更低的開發成本、更完整的生態和工具鏈,也同時嘗試接入更多的業務,體現出它的更大的價值。已經有很多業務方迫不及待的在和我們主動取得聯絡了,未來我們希望 Weex 能夠逐步在集團內開放試用,並最終走向開源。
另外整個技術方案還有很多值得分享的東西,比如 transformer 的實現、元件和 API 的設計思路等,我們會再做針對性的分享和介紹
下一篇:對無線電商動態化方案的思考(三)
相關文章
- 無線動態化解決方案總結:從WeApp到WeexAPP
- Flutter 動態化方案探索Flutter
- iOS應用模組化的思考及落地方案(二)模組化自動構建工具的使用iOS
- Flutter 動態化熱更新的思考與實踐Flutter
- 關於自動化運維的思考-基線運維
- 面對物件的思考(二) (轉)物件
- vite 靜態離線無伺服器部署 方案Vite伺服器
- 基於weex的考拉移動端動態化方案
- 端動態化方案詳細設計
- 貓客頁面內元件的動態化方案-Tangram元件
- Flutter 對狀態管理的認知與思考Flutter
- 支付寶移動端動態化方案實踐
- 關於大型網站技術演進的思考(十)--網站靜態化處理—動靜整合方案(2)網站
- 學校有線與無線一體化網路解決方案
- 查詢重寫對全外連線無效(二)
- 無線網路卡狀態不對問題:已連線 顯示 未連線
- 多容器動態化方案在遊戲SDK中的實踐遊戲
- 一名一線開發對於App架構和元件化的思考APP架構元件化
- Android 元件化方案探索與思考Android元件化
- 無線通訊方案大全
- 關於自動化平臺的動態選單設計(二)
- 我對移動端架構的思考架構
- 對二叉樹遍歷操作的深入思考二叉樹
- 關於前端元件化、狀態管理規範化的思考前端元件化
- 無線端的彈幕實現方案
- [Echarts視覺化] 二.php和ajax連線資料庫實現動態資料視覺化Echarts視覺化PHP資料庫
- 對格式化字串的一些思考字串
- 自動化思考和展望
- iOS元件化方案(二)iOS元件化
- 【深度思考】聊聊JDK動態代理原理JDK
- 大佬是怎麼思考設計MySQL優化方案的?MySql優化
- 天貓客戶端元件動態化的方案——VirtualView 上手體驗客戶端元件View
- 電商交易場景狀態機方案探索及應用
- MyBatis對動態SQL的支援MyBatisSQL
- elasticsearch的字串動態對映Elasticsearch字串
- 對JAVA動態代理的理解Java
- iOS 動態化的故事iOS
- 企業無線覆蓋,企業無線網路,辦公無線區域網方案