eex對顏色和長度單位支持情況和標(biāo)準(zhǔn)CSS不同,如果程序中使用了weex程序不支持的樣式單位,程序運(yùn)行會(huì)出現(xiàn)異常,頁面無法正常渲染。
weex demo page
weex支持的樣式單位具體如下:
支持以下寫法:
.classA { /* 3-chars hex */ color: #0f0; /* 6-chars hex */ color: #00ff00; /* rgb */ color: rgb(255, 0, 0); /* rgba */ color: rgba(255, 0, 0, 0.5); /* transparent */ color: transparent; /* Basic color keywords */ color: orange; /* Extended color keywords */ color: darkgray; }
注意:不支持 hsl(), hsla(), currentColor
6-chars hex是性能最好的顏色使用方式。除非有特殊原因,請使用6-chars hex格式。
在 Weex 中,我們只支持 px 長度單位。
.classA { font-size: 48px; line-height: 64px; }
不支持類似 em,rem,pt 這樣的 CSS 標(biāo)準(zhǔn)中的其他長度單位,百分比目前也不支持。
number可用于以下CSS屬性:
期H5和Hybrid方案的本質(zhì)是,利用客戶端App的內(nèi)置瀏覽器(也就是webview)功能,通過開發(fā)前端的H5頁面滿足跨平臺(tái)需求。比如PhoneGap cordova ionic ……
該方案提升開發(fā)效率,同時(shí)也滿足了跨端的需求。但有一個(gè)問題就是,前端H5的性能和客戶端的性能相差甚遠(yuǎn)。Facebook 推出ReactNative
關(guān)于RN,安利下《ReactJS到React-Native,架構(gòu)原理概述》
Weex與ReactNative 都是基于Yogo渲染骨架做的 跨端框架,一個(gè)基于React,一個(gè)基于Vue,個(gè)人偏好RN,但是Weex 貌似更香。
相對于ReactNative的“l(fā)earn once write anywhere”,weex的: “write once run anywhere”,牛皮更寬廣
關(guān)于Weex的使用,還是看官方文檔好:https://weex.apache.org/zh/guide/introduction.html
Weex的源文件(最新的Weex版本支持的是Vue文件),如果想用React, 也可以用Rax(兼容React接口), 甚至如果可能,可以支持更多的前端框架。因?yàn)楦鶕?jù)Weex設(shè)計(jì)前端框架僅僅是語法層(或者叫DSL), 它與原生渲染引擎是分離的。當(dāng)然自己擴(kuò)展支持另一套前端框架也比較麻煩,需要做不少工作。
在初始化階段, WEEX SDK 會(huì)準(zhǔn)備好一個(gè)js的執(zhí)行環(huán)境。因?yàn)槲覀兪且诳蛻舳伺躩s 代碼的,所以需要一個(gè)js執(zhí)行環(huán)境,這個(gè)執(zhí)行環(huán)境類似于瀏覽器的v8 引擎, 在IOS 上,則是客戶端自帶的 js core。
這個(gè)js執(zhí)行環(huán)境,可以看成是一個(gè)在客戶端上的沙盒,或者是一個(gè)虛擬機(jī)。
為了提升性能,js 執(zhí)行環(huán)境只用在初始化的時(shí)候初始化一次,之后每個(gè)頁面都無須再初始化了。也就是說不管客戶端打開多少個(gè)weex頁面,多個(gè)頁面的 JS 都是跑在同一個(gè)js執(zhí)行環(huán)境中的。
weex-vue-framework 框架 是什么呢?
你可以把 weex-vue-framework 框架當(dāng)成被改造的Vue.js。語法和內(nèi)部機(jī)制都是一樣的,只不過Vue.js最終創(chuàng)建的是 DOM 元素,而weex-vue-framework則是向原生端發(fā)送渲染指令,最終渲染生成的是原生組件。
同時(shí),Weex為了提高Native的極致性能,做了很多優(yōu)化的工作。前端優(yōu)化性能時(shí),會(huì)把業(yè)務(wù)代碼和 vue.js 這類的依賴包分開打包,一個(gè)份是業(yè)務(wù)代碼,一份是打包的框架依賴。
weex 把weex-vue-framework 這類框架依賴內(nèi)置到了SDK中,客戶端訪問Weex頁面時(shí),只會(huì)網(wǎng)絡(luò)請求JS Bundle。由于JSFramework在本地,所以就減少了JS Bundle的體積,每個(gè)JS Bundle都可以減少一部分體積,從而提升了性能。
WXBridge 是 weex 實(shí)現(xiàn)的一種 js 和 客戶端通信的機(jī)制。
js 執(zhí)行環(huán)境和客戶端是隔離的,為了和外界客戶端的世界通信,需要有一個(gè)通信的橋梁。weex 實(shí)現(xiàn)了 WXBrigde, 主要通過 callJS 和 callNative 兩個(gè)核心的方法,實(shí)現(xiàn) js 代碼和客戶端代碼雙向通信。
在完成了上面的初始化之后,weex已經(jīng)做好了準(zhǔn)備,只等著下載 JS bundle 就可開始渲染頁面了。
weex 能讓一套代碼能做成 native 級別的app,主要是做了三件事:
整體工作可以分為三個(gè)部分
1、轉(zhuǎn)換 <template> 為 類JSON的樹狀數(shù)據(jù)結(jié)構(gòu), 轉(zhuǎn)換數(shù)據(jù)綁定 為 返回?cái)?shù)據(jù)的函數(shù)原型。#####
<foo a="{{x}}" b="1" /> --> {type: "foo", attr: {a: function () {return this.x}, b: 1}}.
2、轉(zhuǎn)換 <style> 為 類JSON的樹狀數(shù)據(jù)結(jié)構(gòu)。
.classname {name: value;} --> { classname : { name : value } }.
3、 把上面兩部分的內(nèi)容和 <script> 中的內(nèi)容結(jié)合成一個(gè)JavaScript AMD(AMD:異步模塊規(guī)范) 模塊。#####
<template>
<foo a="{{x}}" b="1" class="bar"></foo>
</template>
<style>
.bar {width: 200; height: 200}
</style>
<script>
module.exports={
data: function () {
return {x: 100}
}
}
</script>
將轉(zhuǎn)換為:
define('@weex-component/main', function () {
module.exports={
data: function () {
return {x: 100}
}
}
module.template={
type: "foo",
attr: {
a: function () {return this.x},
b: 1,
classname: ['bar']
}
}
module.style={
bar: {width: 200, height: 200}
}
})
bootstrap('@weex-component/main')
說明1:除此之外,轉(zhuǎn)換器還會(huì)做一些額外的事情: 合并Bundle ,添加引導(dǎo)函數(shù),配置外部數(shù)據(jù)等等。
說明2:案例來自Weex的官方文檔。當(dāng)前大部分Weex工具最終輸出的JS Bundle格式都經(jīng)過了Webpack的二次處理,所以你實(shí)際使用工具輸出的JS Bundle會(huì)和上面的有所區(qū)別。
實(shí)際上當(dāng)WEEX SDK獲取到JS Bundle后,第一時(shí)間并不是立馬渲染頁面,而是先創(chuàng)建WEEX的實(shí)例。
每一個(gè)JS bundle對應(yīng)一個(gè)實(shí)例,同時(shí)每一個(gè)實(shí)例都有一個(gè)instance id。
我們上文中說過,由于所有的js bundle都是放入到同一個(gè)JS執(zhí)行引擎中執(zhí)行,那么當(dāng)js執(zhí)行引擎通過WXBridge將相關(guān)渲染指令傳出的時(shí)候,需要通過instance id才能知道該指定要傳遞給哪個(gè)weex實(shí)例
在創(chuàng)建實(shí)例完成后,接下來才是真正將js bundle交給js執(zhí)行引擎執(zhí)行。
在實(shí)例創(chuàng)建完成后,接下來就是執(zhí)行JS bundle 了。JS bundle 的結(jié)果是生成Virtual DOM ,然后去patch 新舊 Vnode 樹,根據(jù)diff 算法找出最佳的DOM操作,唯一和瀏覽器不同的是,調(diào)用的是 Native app api ,而不是瀏覽器里面對DOM節(jié)點(diǎn)增刪改查的操作。
Weex 的渲染流程如下圖:
Virtual DOM ->
-> Build Tree -> Apply Style -> Create View -> Update Frame -> Attach Event ->CSS Layout ->Update Frame
->Native/H5 View
輸入:虛擬DOM
輸出:Native UI 頁面
參考文章:
Weex 2:淺說Weex工作原理 https://www.jianshu.com/p/32285c709682
深入理解weex內(nèi)核原理 https://zhuanlan.zhihu.com/p/71064826
轉(zhuǎn)載本站文章《Weex原理及架構(gòu)剖析》,
請注明出處:https://www.zhoulujun.cn/html/webfront/AppDev/Weex/8495.html
文從內(nèi)核角度切入,為大家?guī)鞼eex技術(shù)演進(jìn)之路的分享。
隨著Weex業(yè)務(wù)規(guī)模的擴(kuò)大和業(yè)務(wù)覆蓋場景的豐富,Weex 不僅在性能穩(wěn)定性上面臨越來越大的挑戰(zhàn),在安全隔離方面,也遇到前所未有的風(fēng)險(xiǎn)。
性能方面:例如,去年的“雙11”和今年“雙11”主會(huì)場規(guī)模對比,去年整個(gè)會(huì)場的JS Bundle大小控制在250K以內(nèi),今年主會(huì)場頁面平均達(dá)到500K+,業(yè)務(wù)復(fù)雜度增加了接近2倍,Weex 的加載性能跟JS bundle 的大小基本成正相關(guān);
穩(wěn)定性方面:業(yè)務(wù)場景覆蓋面的提升,從原來的偏展示的場景到偏交互場景的業(yè)務(wù),以及一些常規(guī)業(yè)務(wù)的接入;新的業(yè)務(wù)場景,必然導(dǎo)致新的穩(wěn)定性方面的挑戰(zhàn),事實(shí)也如此;
富交互:引入Gcanvas、AR/VR等富交互場景,對Weex js-native的通信效率要求極高;
安全性:舊引擎的安全漏洞的問題,以及業(yè)務(wù)之間存在相互污染,無法做到安全隔離的問題;
證書問題:Yoga引擎的證書授權(quán)問題;
從三個(gè)方面來闡述Weex 在內(nèi)核重要方向的演進(jìn):JS引擎、Layout 引擎、WeexCore架構(gòu)的演進(jìn);
JS引擎: 我們的目標(biāo)是更快、更穩(wěn)定、更安全、更小;其一:我們投入大量資源在JS引擎的優(yōu)化上,從JS引擎的替換,由原來舊版本的V8 換成最新版本JavaScriptCore;其二:我們開創(chuàng)性地將JS Runtime 運(yùn)行于獨(dú)立的進(jìn)程里,不僅保證主進(jìn)程的穩(wěn)定性,而且加入了智能恢復(fù)的能力;其三:重新考慮Weex 業(yè)務(wù)隔離的安全問題,開發(fā)設(shè)計(jì)了多Context 隔離的方案,保證避免業(yè)務(wù)間互相污染;其四:瘦身,包的精簡;
Layout引擎:Weex項(xiàng)目成立以來,我們一直借用的Facebook的Yoga項(xiàng)目作為我們的布局引擎,但是Layout引擎對于Weex 項(xiàng)目又是如此重要,所以,我們今年10月份開始計(jì)劃開發(fā)全新的Layout引擎開發(fā)的項(xiàng)目,來替換yoga引擎。第一,Layout 引擎作為核心模塊,我們希望去主導(dǎo)演進(jìn)的路線; 第二,F(xiàn)acebook的證書風(fēng)險(xiǎn)不能回避;所以我們決定重新開發(fā)自己的Layout 引擎,并爭取做到更高性能,支持更多布局方式;
WeexCore架構(gòu):今年我們討論最多的就是Weex 后續(xù)如何演進(jìn),在性能穩(wěn)定性方面如何做的更優(yōu),在復(fù)雜業(yè)務(wù)的支持方面如何做的更好。WeexCore 首先是高性能的,用以滿足更復(fù)雜場景業(yè)務(wù)開發(fā),以及提升業(yè)務(wù)開發(fā)體驗(yàn);其次是一個(gè)跨平臺(tái)的內(nèi)核,從DSL的跨平臺(tái)到內(nèi)核的跨平臺(tái)。
JS引擎技術(shù)
眾所周知,JS 引擎至于Weex至關(guān)重要,是Weex 最重要的一個(gè)核心模塊,2017年,我們在JS 引擎的投入也是非常大:
2017-3月~2017-7月:對最新版本的V8和最新版本的JavaScriptCore 做來全面的profile,讓profile數(shù)據(jù)告訴我們?nèi)ミx擇哪個(gè)引擎作為Weex新一代的JS 引擎。經(jīng)過4個(gè)月的努力,終于將最新版本的JavaScriptCore 在手機(jī)淘寶正式版本上線,同時(shí)Weex也是第一個(gè)將JavaScriptCore引擎(javascriptcore引擎apple維護(hù)的,很少在android平臺(tái)商業(yè)化過)集成到手機(jī)淘寶這樣體量的App中,中間遇到的兼容性的問題也是我們最大的挑戰(zhàn)。最終性能提升還是比較明顯的,手淘上Weex整體業(yè)務(wù)首屏加載時(shí)間提高了40%+,并全面支持ES6特性;
2017-7月~2017-10月:新版本的JavaScriptCore 上線以后,Weex的穩(wěn)定性native crash 占比5%左右,按照手淘的穩(wěn)定性要求(<1%)還是有比較大的差距,這個(gè)將是我們2017年雙十一前最大的挑戰(zhàn)。當(dāng)時(shí)Weex穩(wěn)定性小組的同學(xué)出于焦慮中,隨著雙十一臨近,不斷有新Weex 業(yè)務(wù)上線,伴隨著冒出一些的兼容性的問題出來,始終看不到收斂的趨勢。一方面,我們正向地去解決這些適配的問題,另一方面,我們也討論如何徹底地解決JS引擎的穩(wěn)定性的問題;后來,我們想到將JS 引擎獨(dú)立運(yùn)行到單獨(dú)的進(jìn)程里去,這個(gè)方案帶來最大的好處,就是Weex 業(yè)務(wù)的crash 不會(huì)影響主程序的穩(wěn)定性;這個(gè)方案也成了雙十一Weex穩(wěn)定性保障的救命稻草。最終這個(gè)方案在10月份前正式上線,效果非常明顯,Weex 引起的native crash占比一下子從5%下降到0.5%左右。
2017~11月~至今:雙十一之后,JS 引擎項(xiàng)目主要在做兩個(gè)事情,一個(gè)Weex安全隔離方案,另一個(gè)是包精簡優(yōu)化方案;Weex安全隔離方案主要解決頁面隔離的問題,雙十一當(dāng)天也遇到一個(gè)非常嚴(yán)重的全局污染的案例,某個(gè)業(yè)務(wù)不小心污染了全局對象,導(dǎo)致所有的Rax的頁面出現(xiàn)白屏的問題;針對這些案例,我們重新設(shè)計(jì)了Weex 安全隔離的方案,目前安全隔離方案已經(jīng)內(nèi)部灰度中,預(yù)計(jì)2月份正式社區(qū)發(fā)布;
包精簡優(yōu)化方案:主要解決Weex sdk集成了最新版本的JavaScriptCore以后,包大小增大一倍的問題(4.2M左右),包的增大直接增大了App接入的門檻,特別是對包大小非常敏感的App。目前同步一下信息:精簡優(yōu)化方案目前也基本開發(fā)完畢,預(yù)計(jì)可以減少到2.6M左右,預(yù)計(jì)也是2月份上線;
獨(dú)立進(jìn)程化
問題
同一個(gè)進(jìn)程中,與主App存在資源競爭,尤其是內(nèi)存問題比較突出,JavaScriptCore雖然執(zhí)行性能提升了,但對內(nèi)存的消耗也同時(shí)增大不少,所以替換成JSC以后,Weex的內(nèi)存問題導(dǎo)致Crash也明顯上升;
獨(dú)立進(jìn)程的方案本身比較Hack,再加上Android生態(tài)的碎片化,開發(fā)過程中也遇到很多適配問題,比如在某些機(jī)型上獨(dú)立進(jìn)程拉不起來,導(dǎo)致業(yè)務(wù)渲染失敗;
JavaScriptCoe引擎本身對android平臺(tái)適配比較差,沒有比較大體量的App在線上應(yīng)用過;
優(yōu)勢
進(jìn)程獨(dú)立以后,完全和主App的進(jìn)程隔離,避免了進(jìn)程資源競爭導(dǎo)致crash的問題,Weex的crash也不會(huì)引起主進(jìn)程的crash;
Weex 原有的三個(gè)線程架構(gòu),JS 線程任務(wù)被并行成兩個(gè),JS獨(dú)立的進(jìn)程和原來JS線程,整體增強(qiáng)了JS任務(wù)執(zhí)行的并發(fā)性,抵消了方案本身的IPC通信的性能損耗;
獨(dú)立進(jìn)程后,我們加入了自修復(fù)的能力,增強(qiáng)了JS Runtime進(jìn)程的自動(dòng)重置功能,解決JS Runtime 異常后的無法自動(dòng)恢復(fù)的問題,極大地保障業(yè)務(wù)的穩(wěn)定性;
SandBox機(jī)制
Weex 原有的設(shè)計(jì),所有Weex頁面包括JSFrameWork 都是運(yùn)行在同一個(gè)JS Context里,并在JS層面,對全局的JS 變量做了freeze操作,防止被其他業(yè)務(wù)頁面污染。這個(gè)設(shè)計(jì)主要還是出于高性能和安全性的綜合考量。
2017年雙十一出現(xiàn)的全局污染的問題,讓我們重新思考Weex Context的安全隔離的方案,安全穩(wěn)定高于一切。經(jīng)過新的討論后,我們決定針對每個(gè)Weex頁面都創(chuàng)建一個(gè)JS Context 作為獨(dú)立的運(yùn)行環(huán)境,頁面依賴的全局對象由Global Contex統(tǒng)一生層并傳遞給每個(gè)頁面的Contex;傳輸?shù)倪^程,我們做了兩個(gè)非常重要的操作:
1)對傳輸?shù)膶ο笞鰂reeze操作;
2)在javaScript引擎層面,通過native的SetPrototype接口切斷原型鏈的關(guān)系;這樣就徹底解決了頁面間互相污染的問題。該方案預(yù)計(jì)2月份正式上線。
Layout 引擎
全新的Layout引擎參考了 Google的FlexLayout的算法流程,重新實(shí)現(xiàn)了Weex的 Flex布局,目前性能和功能方面基本和yoga保持一致,后續(xù)會(huì)做一些性能優(yōu)化。至于未來如何演進(jìn),團(tuán)隊(duì)同學(xué)討論幾個(gè)關(guān)鍵的步驟:
自主開發(fā)全新的高性能的跨平臺(tái)Layout引擎,統(tǒng)一由C++實(shí)現(xiàn),IOS/android 兩端復(fù)用同一套代碼;
擴(kuò)展更多的布局方式,比如Gird布局、Absolute布局等
編譯器或服務(wù)端做預(yù)布局,提升端測的布局效率等;
該方案預(yù)計(jì)2月份正式上線。
Weex 作為一個(gè)跨平臺(tái)的開發(fā)框架,在Android/ IOS/HTML 三端實(shí)現(xiàn)跨平臺(tái)一致性非常重要。目前Weex 核心渲染流程分平臺(tái)實(shí)現(xiàn),不僅多人維護(hù)導(dǎo)致不可避免的邏輯實(shí)現(xiàn)差異,而且對于后續(xù)新平臺(tái)擴(kuò)展成本也非常高(核心渲染流程需要重新實(shí)現(xiàn))。因此,想到抽象統(tǒng)一Weex 核心解析渲染流程,通過C + + 語言實(shí)現(xiàn),實(shí)現(xiàn) ios、android 平臺(tái)核心邏輯統(tǒng)一,不僅可以增強(qiáng)平臺(tái)間的一致性,降低維護(hù)成本,以及擴(kuò)展平臺(tái)的成本。通過C+ +代碼執(zhí)行效率要高于JAVA,同時(shí)還可提高Android端的代碼執(zhí)行性能。
提供標(biāo)準(zhǔn)的Weex Dom API Layer,簡化DSL的接入成本,將大部分JSFramework native化;
抽象Weex平臺(tái)無關(guān)的、核心的處理邏輯,android和IOS的porting層盡量做薄,一方面提高代碼的復(fù)用率,另一方面降低新平臺(tái)的擴(kuò)展成本;
架構(gòu)設(shè)計(jì)上的高可用,通用的模塊可插拔,例如JS engine 模塊和Layout engine模塊能低成本地切換;
核心技術(shù)模塊比如JS engine 等能標(biāo)準(zhǔn)化輸出,服務(wù)更多的業(yè)務(wù)場景;
(本文作者飲源,阿里巴巴技術(shù)專家)
*請認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。