天天看點

對無線電商動态化方案的思考(二)

weex 是一款輕量級的移動端跨平台動态性技術解決方案!

體積小巧,文法簡單,友善上手

業務方可自行橫向定制 native 元件和 api

快速加載,快速渲染,體驗流暢

擁抱标準:基于 web 标準設計文法

響應式界面: 通過簡單的模闆和資料綁定輕松解決資料和視圖的同步關聯問題

多端統一:ios、android、html5 多端效果一緻,撰寫一次就可以輕松達到跨平台的一緻性,無需針對多套平台單獨開發,省時省力

複雜邏輯描述:動态性不隻展現在展示效果的動态性上,更展現在可以實時調整複雜的資料處理方式和邏輯控制方式

元件化:元件之間通過 webcomponents 的設計完美的隔離,并可以通過特定的方式進行資料和事件的傳遞

生态&鍊路:我們為 weex 的開發者和使用者在不同次元上提供了各式各樣的工具和平台,包括代碼打包工具、開發者調試工具、部署平台、playground、經典案例、入門指南和詳盡的文檔等。你不是從零開始,你也不是一個人在戰鬥!

首先,我們像開發 webcomponents 一樣,把一個元件分成 <code>&lt;template&gt;</code>、<code>&lt;style&gt;</code>、<code>&lt;script&gt;</code> 三部分,剛好對應一個元件的界面結構、界面樣式、資料&amp;邏輯。

細節1:順便說一句,這也是我們認為描述界面的最佳實踐。

代碼示例:

顯然這些代碼是不會被 native app 識别的,我們要想辦法讓這些代碼可運作。是以我們同時做了三件事:

在本地用一個叫做 transformer 的工具把這套代碼轉成純 javascript 代碼

在用戶端運作一個 javascript 引擎,随時接收 javascript 代碼

在用戶端設計一套 js bridge,讓 native 代碼可以和 javascript 引擎互相通信

是以緊接着第二步,就是用 transformer 對代碼進行轉換,變成用戶端可運作的 javascript 代碼

其實本地開發還有一點很重要,就是把複雜的界面通過元件化的方式進行分解,并合理的建立元件之間的組合和調用關系。

最終,我們把簡單元件組合成複雜的界面,并通過 transformer 打包成一個完整的程式包 (主體是一段 javascript 代碼)

細節2:由于 weex 元件的開發和 web 元件的開發非常接近,但是對标準的支援範圍和一些細節是有不同之處的,我們會貼心的在 transformer 裡加入了一些友情提醒,幫助大家回避常犯的書寫錯誤。

對無線電商動态化方案的思考(二)

上一節已經提到了,我們在用戶端會運作一個 javascript 引擎并且有 js bridge 通信機制。這裡再介紹具體一些:

native 渲染和 javascript 引擎之間,主要進行三類通信:

界面渲染,單向 (js -&gt; 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

我們在服務端提供了基礎的程式包釋出,給每個程式包一個特定的 page id,然後為用戶端提供通用的服務,通過 page id 擷取程式包,這樣本地開發、動态實時部署、用戶端動态化渲染和邏輯處理就完美的串聯在一起了

細節8:實際上,除了界面本身可以動态化之外,用戶端的 js 引擎的代碼、還有部分 native 的實作,我們也準備了相應的動态化機制,也就是說用戶端的動态能力本身也是具有動态性的

我們還會面對這樣的場景,就是一個用戶端的業務,會通過微網誌之類的管道進行轉播和推廣,當使用者手機裡剛好安裝了手機淘寶用戶端,那麼會直接“拉起”用戶端進行相應的界面展示,如果沒有裝手機淘寶,則需要在浏覽器裡展示一個相同或接近的界面。自然 weex 技術方案支援的業務也有這樣的需求。是以我們同時提供了 html5 版本的技術方案,同一份 javascript 程式包,可以同時通過用戶端的 js bridge 渲染成為 native 界面,也可以通過浏覽器渲染成為 web 界面。我們的做法也非常簡單,就是把 js bridge 背後的 native 處理邏輯同構成了 html5 版本。然後釋出這樣的一個頁面。

細節9:我們能夠同構 html5 版本和 native 版本,主要歸功于我們在 js bridge、元件定義、api 定義方面的高度抽象——當然 html5 的版本在性能和體驗上确實有一定的劣勢,并不是最理想化的效果,是以核心的主戰場還是用戶端,這也和目前的移動網際網路的形态相吻合

綜上所述,整個 weex 的工作原理大緻可以用一張圖來表述:

對無線電商動态化方案的思考(二)

我們緻力于把開發體驗、網絡傳輸的大小、運作時的開銷控制做到極緻,并且盡可能的降低多端适配和優雅降級的成本

我們對元件的定義和業務功能預留了很好的橫向可擴充能力,這也業務方可以自由定制屬于自己的 native 元件和 api,進而在後期可以通過實時釋出不同的程式包來進行動态化控制。同時也因為它的橫向可擴充性,weex 的核心可以非常小,非常易于融入現有的無線技術體系

我們在網絡傳輸、執行個體初始化、js 運算、native 渲染能力等方面做了非常針對性且深入的優化,尤其是針對中低端安卓機,不論是加載時間還是運作時的流暢度,都比之前的方案有質的飛躍。我們對 cpu、記憶體、幀率、首屏渲染時間等核心性能名額也一直保持高度的關注,也建立了相應的線上監控和資料統計機制。而更多可優化的空間和方案我們還在不斷的進行優化嘗試。

下圖是今天淩晨舊金山 qcon 上 weex 技術方案的首次公開分享中的一頁性能表現對比圖,大家可以感受一下:

對無線電商動态化方案的思考(二)

這就是 weex,如上一篇文章所介紹的:

緻力于移動端

能夠充分排程 native 的能力

能夠充分解決和回避性能瓶頸

能夠靈活擴充

能夠多端統一

能夠優雅“降級”到 html5

能夠保持較低的開發成本

能夠快速疊代

能夠輕量實時釋出

能夠融入現有的 native 技術體系

能夠工程化管理和監控

目前 weex 還在努力達到更高的性能、更高的擴充性、更低的開發成本、更完整的生态和工具鍊,也同時嘗試接入更多的業務,展現出它的更大的價值。已經有很多業務方迫不及待的在和我們主動取得聯系了,未來我們希望 weex 能夠逐漸在集團内開放試用,并最終走向開源。

另外整個技術方案還有很多值得分享的東西,比如 transformer 的實作、元件和 api 的設計思路等,我們會再做針對性的分享和介紹

繼續閱讀