Weex詳解:靈活的移動端高性能動態化方案

wKioL1crRsag2AT8AADJQq3gM1M044.jpg


在2016年4月份的QCon上,阿里巴巴資深總監,淘寶移動平臺及新業務事業部、阿里百川負責人莊卓然(花名南天)宣佈阿里移動端跨平臺開發框架Weex開始內測,並將於6月份開源。在QCon的第二天,阿里技術專家徐凱(花名鬼道)和阿里前端開發專家趙錦江(花名勾股)向參會者做了《Weex——靈活的移動端高性能動態化方案》的演講,對這一技術方案進行了詳細的剖析。


以下爲演講內容的整理:


昨天南天宣佈Weex啓動開源內測,截至到今天中午,我們統計申請內測用戶突破1400人,大家的熱烈程度遠遠超過我們的設想,非常感謝大家支持。


在我們對移動開發最佳實踐的思考中,我們認爲移動開發的未來是更平衡的方案,一定是性能和動態性兼得。第二個,它一定是開放互聯的,PC端一直也是這樣的,也是非常好的狀態。我們覺得移動互聯網將來肯定也是基於更大衆化的技術體系,沒有平臺之間的隔閡,簡單直接易用,這是我們最希望看到的。基於這些設想,我們有了Weex方案。


Weex是從去年雙十一的時候第一次在我們正式產品中使用,承載了雙十一主會場的工作。有人會問,Weex是不是除了做主會場別的地方就比較吃力呢?從去年雙十一到現在,包括我們自己的嘗試和阿里內網做開源內測活動,大家也貢獻了很多內容,包括昨天Keynote演示的殭屍動畫,掃雷、計算器都有,各種豐富場景的東西都可以通過Weex做出來,不僅僅是做主會場的技術方案。


對移動端開發模型的理解


我們談談Weex團隊對移動端開發模型的理解。


wKiom1crRgXT9pAwAABbpda0_bA538.jpg


今天絕大多數移動端APP是這樣一個最佳實踐,首先把移動端所有界面拆分成各個page,中間有一個路由的控制邏輯。同時我們需要移動端各種各樣豐富的能力,通過API的形式提供給開發者。這是我們認爲一個比較理想的開發模型。


從開發模型來講,我們比較傾向於通過標準化的一些東西,包括HTML、CSS、JS這些前端非常快速易用好學的語法作爲一個開發體驗,提供給開發者。這裏強調一下,我們語法設計尊重了Web標準,包括核心源代碼都是從Vue.js——一個非常優秀的MVVM前端框架來的。我們的開源內測同步在海外通過Vue.js的Twitter等途徑進行宣傳,得到了非常熱烈的反響,短短一天時間內,老外們的關注度和熱情也是出乎我們的意料。有些人非常興奮和激動,想知道什麼時候看到源代碼,和我們聯繫,我們覺得也是值得高興的一件事情。


Weex的組件化與DSL語法


Weex編寫的頁面天然的支持組件化,首先,我們的界面可以是一個組件化的,把一個複雜界面分成每個組件,剛纔演示的都是簡單的組件,每個組件都可以看成是一段template,style,script,放到模型裏,對應到界面的結構,樣式細節,行爲定義。在view裏面我們傾向於把數據和視圖當中需要展示和需要有動態變化的部分做一個數據綁定,綁定之後我如果想更改界面的話,通過改變數據就可以做到。這是從model到view非常順暢的控制邏輯和代碼方式,這也算是Weex上層語法設計的基礎。如果大家做的界面比較複雜,可能有更多細節,或者做更多分解,我們需要從整體上對整個界面以模塊爲單位作爲拆解,對每個模塊做定義,如果界面足夠複雜,可以先拆成組件,再把每個組件具體內容進行定義。定義方式就是通過結構、樣式和行爲角度對它進行定義,通過有機方式把這些組件結合起來,完成頁面開發。


wKioL1crRurjPl0QAABfKoxa6PI897.jpg


關鍵語法簡述。首先看看template,大概有幾個元素。它首先是virtual DOM tree展示,包括事件綁定,組件跟組件之間還可以嵌套,還可以有子元素,這是整體template結構。再往下是style,一方面可以把共用樣式抽樣出來,另一方面可以讓template結構更加清晰,不至於陷入到整個具體樣式描述當中去。我們在這邊會做一些收斂,我們只支持了單個class的selector寫法,主要從性能角度考慮。傳統的css可以理解爲是一個N對N的數據庫,匹配過程非常複雜,性能也得不到非常好的保證,我們爲了保證性能,我們把selector約定在單個class,性能可以保證。


wKioL1crRvaztj6hAABLHaljSzU575.jpg


另外,我們的樣式天然默認的就是scoped,大家可以放心定義各種各樣的classname,不擔心和其他組件相沖突,全局衝突是CSS“七宗罪”中的一個,其實這也是我們非常重視的,所以在實踐上我們把它做到了scoped。


其他的,可以做一些展示的控制,比如if、repeat剛纔演示中也提到了。剛纔沒有演示到的這個很特殊,append,在性能不是那麼好的Android下,界面加載過程用戶是可感知的,不是一瞬間做到的。我們加這個值可以讓你精細化展示界面的顆粒度,如果上層做了append等於tree的話,裏面一系列東西會做一次性的加載,這是從性能優化角度做的特殊設計。再是id,我們可以通過在這裏面寫id拿到這個值,把它當作參數傳給API做處理。


我們現在已經支持的組件,除了剛纔演示的div空白容器、圖片、文本之外,我們還支持slider:一個性能比較好的滑塊組件,還有list,性能上自動做內存管理和資源管理的組件,把性能和幀率各方面都做的比較好。還有input,輸入框我們是最近才做的,也是剛支持的,可能還有試驗性階段的小東西。在這個範圍之外,業務方可在上層橫向擴展,稍後會有具體介紹。這是template和style部分的介紹。


樣式部分我們支持flexbox,非常靈活通用便捷的佈局方式,有了flexbox,只要你的界面可以拆分成豆腐塊的,都可以用flexbox來做,同時我們還做了fixed和sticky這兩個特殊的佈局,sticky意思是如果有一個列表分類,比如聯繫人ABC字母滾到屏幕外,會停在最上面,那個效果就是sticky,當你划走它就會跟着走,在各種手機應用當中是一個比較常見的東西。同樣,更多的樣式每個組件也可以自己定製,非常靈活。


從事件角度,click是基礎事件,change在表單的值改變和滑快的第幾幀改變時都會有,同時我們加入了appear和disappear,當我通過任意操作進入屏幕區域內,會觸發appear事件,出來以後會觸發disappear事件,非常適合用在一些lazyload之類的邏輯場景。這些事件也可以在各自組件中做橫向擴展。


Script部分剛纔例子也提到了,主要是viewmodel設計,最主要的是data和methods,值修改之後相應數據綁定的值也會發生改變。除此之外我們提供了生命週期的方法,創建的時候,數據監聽完成的時候,渲染完成的時候,你只要把這三個方法同樣寫在data和methods下面。還有原生 API,剛纔演示的時候也出現了,這裏不多介紹。


組件化搭建很複雜,通過定義子組件,比如我上面有一個foo組件,通過foo標籤就可以把foo嵌入到別的組件中來,數據傳遞的話就可以在foo組件中寫a和b,foo元素就可以通過這種方式傳遞給子元素,然後進行處理。再是組件中間的通信,也是事件機制,每個組件可以通過off,對自定義事件進行監聽和解綁定,想觸發事件也有三個方法:只傳給自己、dispatch向上冒泡給所有父組件、$broadcast廣播給所有子組件,這些設計和Vue非常相近的,做到組件之間的通信。


除了剛纔介紹的這些特性,我們未來還會提供更豐富的、相信也是開發者需要的、平時開發中會碰到的場景,更豐富的表單,還有更好的動畫展示,包括複雜手勢場景。在這方面,無論是性能還是開發體驗、最終效果都能夠非常好,這是團隊正在努力在未來提供給大家的。同時我們希望收集和分享更多相關素材,做出更多工具,提供更好的開發者體驗給大家。


更多的內容,包括剛纔演示的Playground App都可以通過我們的官網找到,現在處在開源內測階段,大家提交申請,通過以後可以訪問倉庫,瞭解更具體的內容。


Weex的工作原理


wKiom1crRi6ySDxLAAB36r8Y-yg893.png


這張圖大家都不陌生,前面也提到了,勾股說的主要是DSL這層。再往下到了Virtual DOM和Render層;H5,我刻意把它用不一樣的顏色標出來,想讓大家知道我們設計之初就考慮到希望在三端上能夠展現,所以這個地方稍微加亮一些。


wKioL1crRxCSmeWbAABjuy2SRJs362.jpg


我們把剛纔這張圖再稍微展開一下,最上面是我們的DSL,我們一般叫Weex文件,通過transformer這層,部署到Server,服務端就完成了。大家不用擔心我們的轉換是不是有性能問題,因爲這在服務端就已經完成。到了客戶端,第一層是我們的JS-Framework,最後到RenderRengine,再往下看,左邊是我們的DSL文件,右邊是轉換出來的jsbundle,在DSL中的template會將我們的類型和子節點都表示出來,將classList轉化成基本語法約定,包括自變量的轉換。最後是腳本,腳本基本上是直譯過來。輸入是Virtual DOM輸出是native或者H5 view,還原成內存中的樹型數據結構,再創建view,把事件綁定在view上,把view基本屬性設上去。虛線是在native上經歷一個過程,在H5上相當於把這個事情交給webkit LayoutEngine去做,把所有元素尺寸和位置重新調整。整個這張圖基本上講清楚了Weex Render流程,我們會分三個線程,不同的線程負責不同的事情,讓JS線程優先保障我們的流暢性,未來我們會有更多的技術文檔,比較細節的放出來。


Weex的性能、擴展以及可用性


下面是在整個Weex架構上比較關鍵的點,這些可能是我們目前關注度最高的,包括性能、擴展以及可用性。


wKioL1crRxzg-Z3ZAABoRnUbgT8895.jpg


首先是性能,我們內部有這樣一個壓測頁面,我們同學把benchmark放在Playground,大家如果下載是能夠看到的。在我們內部做壓測的時候調到三千個節點,大概10屏,一屏有三個卡片,一個卡片有100個節點左右。我們看一下數據,第一個性能對比是我們的加載時間,同樣一個頁面1300、1600,也不算特別大,20%左右,幀率大概差開一幀,scroller差不多,內存這塊會好一點,因爲我們這邊用了recycle view,會好一些。再往下是CPU,靜默CPU消耗,還有運行過程中CPU的峯值。靜默CPU接近0點幾,我們不做16毫秒的輪循,如果做16毫秒輪循CPU會更高一些。


wKiom1crRlSC8SraAABHsr12TtU260.jpg


這是一個真實業務數據,3月份頁面上線之後我們看了一下,這張頁面是一個活動,3月份新風尚的活動,這個活動頁面沒有用List,沒有特別做內存對比,這兩個設備定義爲低端機,幀率差壓比較明顯,無論是數據還是實際中的體驗,流暢性大概是這樣的差距。我們說性能往往都會提到幀率、加載時間,但往往會忽略一個事情,Native UI開發中通常沒有JS資源在服務端加載,Weex以及類似動態化方案有一個副作用,我們有一個JS必須從服務端下載,我們把JS內置到客戶端裏,免除下載的問題,這裏涉及到一整套的策略。我們內部有一套機制,之後會把這套機制作爲獨立的技術產品開放出來。


wKioL1crRzayXJlTAACduNBPOW4526.jpg


下一個是我們的兼容性。兼容性不只是對Weex,對偏內核型項目都會有這個問題,舉一個Weex例子,第一排是我們的業務代碼,再往下看,上面兩次變遷,一直到客戶端,整個場景會變成N的立方。舉一個具體數字,我的業務代碼改了三個版本,(英文)三個版本,最後會有三的立方27個場景。兼容性是我們一直重視的問題。我們做了幾件事情,首先單測保證,包括JS和H5的單測,保證最最基礎的UT本身帶來的含義。第二個是JS單測環境,我們一般會將(英文)跑在(英文環境下,但和JS安全還是有差異。再往下是自動化工作,這塊工作細分也可以分成兩塊:一塊是我們針對截圖比對,比如我們同學會說我們設置了很多各種各樣細節屬性,怎麼說你渲染出來的就是你實際想要的,通過API級別的效果不是很好。所以這種我們會通過截圖,將最終產生的結果和我們意料中的結果進行圖形比對,比較老的成熟的內核上面做的比較成熟,也會有一些借鑑。另外是layout results,相當一部分,包括model,包括其他的佈局類的,其實我們完全可以通過一個元素,最終它的寬高,左上角的點,通過基本的信息,讓它完成測試的過程。所以我們經過這兩塊工作,一旦成熟,我們會盡快放到上面。


再就是擴展性,我們先回顧一下這張圖,前面也有提到,目前Weex給大家直觀的感覺是可以用Weex寫很多頁面,有一個路由機制,內部叫導航,幫助你將頁面進行串連,我們提供很多features,由這樣的形式構成Weex大家所看到的一個結構。細分來看,如果你擴展一個component,特定的一些方法,使用anotation標識輸入輸出參數。這是一個module,在DSL上看到的是API,底層就是module。如果擴展module也是一樣的,這是很簡單的跳轉,基本信息帶上去,實現業務功能,一個module就完成了,很簡單。


wKioL1crR2bgnA2sAAB7njZURgg933.jpg


這是路由,整個路由在APP Framework中只是一個環節,所以接下來的規劃還是有許多東西需要做的,單獨看components這塊,包括前面兩個,再往下是lifecycle考慮,再是動畫跟手勢,這塊我們覺得都是最基礎的東西。再往下是全局的多個Weex容器之間通信機制,數據存儲、網絡,包括下面涉及到的一堆傳感器,包括基礎的FS,還有偏業務類的東西,整個東西都有同步在做,但現在的工作集中是在這塊。回到剛纔的老問題,如果我們開放一個module,上層提供API,中間提供adapter,如果提供自由實現就將默認的覆蓋掉,比如手淘裏面(TBxxx),把默認頁面覆蓋掉(WXxxx),對大家來說在已有能力增強,或者是增加新的組件,或者是新的module上,目前已經達到這個狀態。


wKioL1crR3ewb6YqAACTwCf2C3I485.jpg


最後是我們的可用性,前面說的比較多,這塊秀幾張圖就好了。這是我們的工具鏈,紅色代表完成的,黃色是五月份、六月份就會完成,在六月正式開源之前。剩下一些東西是我們內部正在討論以及會安排時間逐步完成的東西,這些都是工具。我們首先給大家提供一個playground,可以掃碼,也有自帶的examples。第二個是調試工具,chrome dev tools常見的功能裏面都有。再是腳手架,大家如果只是玩玩的話用playground就可以了,如果自己做一個獨立的APP,你要用Weex做的話我們也會給你提供腳手架。我們的規劃中獨立項目,不是最終的名字,最終會有一個類似APPHub的工具。包括信息察看,在界面上展示結構。這是剛纔提到的例子,這個是playground裏面的,雖然截圖是iphone效果和android是完全一樣的,已經用Weex現有功能做出比較好玩的組件庫。然後是我們的文檔,包括項目guide、reference、toolchain,細節我不多說了,大家可以去看看。


Weex的集成方式


目前Weex有三種集成方式:


  1. 全頁模式 
    o 目前支持單頁使用或整個app使用weex開發(還不完善,需要開發router和生命週期管理)這是主推的模式,可以類比RN。


  2. Native Component模式 


    o 把weex當作一個iOS/Android組件來使用,類比ImageView。這類需求遍佈手淘主鏈路,如首頁、主搜結果、交易組件化等,和業務同學溝通下來這類Native頁面主體已經很穩定,但是局部動態化需求旺盛導致頻繁發版,解決這類問題也是Weex的重點。 


    o 這也涉及到如何讓Native同學快速上手“準Web”開發,有意思的話題,大家多給些建議。


  3. H5 Component模式 


    o 在H5種使用Weex,類比WVC。一些較複雜或特殊的H5頁面短期內無法完全轉爲Weex全頁模式(或RN),比如貓超、互動類頁面、一些複雜頻道頁等。針對這個痛點我發起過WVC項目,並在實際業務中驗證了這樣的想法:在現有的H5頁面上做微調,引入Native解決長列表內存暴增、滾動不流暢、動畫/手勢體驗差等問題。 


    o WVC將會融入到Weex中,成爲Weex的H5 Components模式。 
    這3種模式幾乎涵蓋了淘系業務上的動態化需求(針對Native)或體驗提升需求(針對H5)。更有趣的是這3種模式的技術基礎是一致的,這非常重要,意味着:業務方可以使用Native或H5 Component模式 解決實際的業務痛點,同時平滑過渡到Weex全頁模式。期待Weex成長壯大到AppFramework的那天。


最後是我們過去雙十一到現在大概五個多月時間做的一些事情。首先我們做了原型版本,再將原型版本獨立出獨立客戶端可使用的SDK,擴展樣式和佈局,將基礎的component做了擴展,這兩個月集中在工具,還有open source上的工作,最後是六月底就會開放出來。


阿里百川(baichuan.taobao.com)是阿里巴巴集團無線開放平臺,通過“技術、商業及大數據”的開放,提供移動場景下的高內聚、開放式、行業領先的技術產品矩陣、成熟的商業組件和完善的服務體系,幫助移動開發者快速搭建APP、加速APP商業化進程,全方位賦能移動開發者及移動創業者。

wKioL1crR6SCub2pAACLR_djx4M481.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章