整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

weex程序开发支持css单位简介

weex程序开发支持css单位简介

eex对颜色和长度单位支持情况和标准CSS不同,如果程序中使用了weex程序不支持的样式单位,程序运行会出现异常,页面无法正常渲染。

weex demo page

weex支持的样式单位具体如下:

CSS color 单位

支持以下写法:

.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格式。

CSS length 单位

在 Weex 中,我们只支持 px 长度单位

.classA { 
 font-size: 48px; 
 line-height: 64px; 
}

不支持类似 em,rem,pt 这样的 CSS 标准中的其他长度单位,百分比目前也不支持。

CSS number 单位

number可用于以下CSS属性:

  • opacity : 取值范围为 [0, 1] 区间。默认值是 1,即完全不透明;0 是完全透明;0.5 是 50% 的透明度。
  • lines : 正整数,指定最大文本行数,默认值为0,表示不限制最大行数。如果文本不够长,实际展示行数会小于指定行数。
  • flex : flex 属性定义了 flex 成员项可以占用容器中剩余空间的大小。如果所有的成员项设置相同的值 flex: 1,它们将平均分配剩余空间. 如果一个成员项设置的值为 flex: 2,其它的成员项设置的值为 flex: 1,那么这个成员项所占用的剩余空间是其它成员项的2倍。

期H5和Hybrid方案的本质是,利用客户端App的内置浏览器(也就是webview)功能,通过开发前端的H5页面满足跨平台需求。比如PhoneGap cordova ionic ……

该方案提升开发效率,同时也满足了跨端的需求。但有一个问题就是,前端H5的性能和客户端的性能相差甚远。Facebook 推出ReactNative

关于RN,安利下《ReactJS到React-Native,架构原理概述》

Weex与ReactNative 都是基于Yogo渲染骨架做的 跨端框架,一个基于React,一个基于Vue,个人偏好RN,但是Weex 貌似更香。

相对于ReactNative的“learn once write anywhere”,weex的: “write once run anywhere”,牛皮更宽广

关于Weex的使用,还是看官方文档好:https://weex.apache.org/zh/guide/introduction.html

Weex的源文件(最新的Weex版本支持的是Vue文件),如果想用React, 也可以用Rax(兼容React接口), 甚至如果可能,可以支持更多的前端框架。因为根据Weex设计前端框架仅仅是语法层(或者叫DSL), 它与原生渲染引擎是分离的。当然自己扩展支持另一套前端框架也比较麻烦,需要做不少工作。



Weex架构分析

js的执行环境

在初始化阶段, WEEX SDK 会准备好一个js的执行环境。因为我们是要在客户端跑js 代码的,所以需要一个js执行环境,这个执行环境类似于浏览器的v8 引擎, 在IOS 上,则是客户端自带的 js core。

这个js执行环境,可以看成是一个在客户端上的沙盒,或者是一个虚拟机

为了提升性能,js 执行环境只用在初始化的时候初始化一次,之后每个页面都无须再初始化了。也就是说不管客户端打开多少个weex页面,多个页面的 JS 都是跑在同一个js执行环境中的

weex-vue-famework 框架

weex-vue-framework 框架 是什么呢?

你可以把 weex-vue-framework 框架当成被改造的Vue.js。语法和内部机制都是一样的,只不过Vue.js最终创建的是 DOM 元素,而weex-vue-framework则是向原生端发送渲染指令,最终渲染生成的是原生组件

同时,Weex为了提高Native的极致性能,做了很多优化的工作。前端优化性能时,会把业务代码和 vue.js 这类的依赖包分开打包,一个份是业务代码,一份是打包的框架依赖。

weex 把weex-vue-framework 这类框架依赖内置到了SDK中,客户端访问Weex页面时,只会网络请求JS Bundle。由于JSFramework在本地,所以就减少了JS Bundle的体积,每个JS Bundle都可以减少一部分体积,从而提升了性能。

WXBridge 通信

WXBridge 是 weex 实现的一种 js 和 客户端通信的机制

js 执行环境和客户端是隔离的,为了和外界客户端的世界通信,需要有一个通信的桥梁。weex 实现了 WXBrigde, 主要通过 callJS 和 callNative 两个核心的方法,实现 js 代码和客户端代码双向通信。

在完成了上面的初始化之后,weex已经做好了准备,只等着下载 JS bundle 就可开始渲染页面了。

Weex工作原理分析

weex 能让一套代码能做成 native 级别的app,主要是做了三件事:

  • 在本地用一个叫做 transformer 的工具把这套代码转成纯 JavaScript 代码
  • 在客户端运行一个 JavaScript 引擎,随时接收 JavaScript 代码
  • 在客户端设计一套 JS Bridge,让 native 代码可以和 JavaScript 引擎相互通信



Weex源码转换成JS Bundle

整体工作可以分为三个部分

1、转换 <template> 为 类JSON的树状数据结构, 转换数据绑定 为 返回数据的函数原型。#####

<foo a="{{x}}" b="1" />   -->   {type: "foo", attr: {a: function () {return this.x}, b: 1}}.

2、转换 <style> 为 类JSON的树状数据结构。

.classname {name: value;}  -->  { classname :  { name :  value } }.

3、 把上面两部分的内容和 <script> 中的内容结合成一个JavaScript AMD(AMD:异步模块规范) 模块。#####

<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>

将转换为:

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:除此之外,转换器还会做一些额外的事情: 合并Bundle ,添加引导函数,配置外部数据等等。

说明2:案例来自Weex的官方文档。当前大部分Weex工具最终输出的JS Bundle格式都经过了Webpack的二次处理,所以你实际使用工具输出的JS Bundle会和上面的有所区别。

获取到JS Bundle后创建 weex 实例

实际上当WEEX SDK获取到JS Bundle后,第一时间并不是立马渲染页面,而是先创建WEEX的实例。

每一个JS bundle对应一个实例,同时每一个实例都有一个instance id。

我们上文中说过,由于所有的js bundle都是放入到同一个JS执行引擎中执行,那么当js执行引擎通过WXBridge将相关渲染指令传出的时候,需要通过instance id才能知道该指定要传递给哪个weex实例

在创建实例完成后,接下来才是真正将js bundle交给js执行引擎执行


在实例创建完成后,接下来就是执行JS bundle 了。JS bundle 的结果是生成Virtual DOM ,然后去patch 新旧 Vnode 树,根据diff 算法找出最佳的DOM操作,唯一和浏览器不同的是,调用的是 Native app api ,而不是浏览器里面对DOM节点增删改查的操作。


Native渲染

Native 渲染引擎提供客户端组件(Component)和模块(Module)

  • 组件(Component):在屏幕内可见,有特定行为,能被配置不同的属性和样式,能响应用户交互,常见的组件有: <div>、<text>、 <image>。
  • 模块(Module): 是一组能被JS Framework调用的API. 其中的一些能以异步的方式调用JS Framework, 例如: 发送HTTP请求。

Weex 的渲染流程

Weex 的渲染流程如下图:

Virtual DOM ->

-> Build Tree -> Apply Style -> Create View -> Update Frame -> Attach Event ->CSS Layout ->Update Frame

->Native/H5 View

输入:虚拟DOM

  1. 构造树结构. 分析虚拟DOM JSON数据以构造渲染树(RT).
  2. 添加样式. 为渲染树的各个节点添加样式.
  3. 创建视图. 为渲染树各个节点创建Native视图.
  4. 绑定事件. 为Native视图绑定事件.
  5. CSS布局. 使用 css-layout 来计算各个视图的布局.
  6. 更新视窗(Frame). 采用上一步的计算结果来更新视窗中各个视图的最终布局位置.

输出:Native UI 页面





参考文章:

Weex 2:浅说Weex工作原理 https://www.jianshu.com/p/32285c709682

深入理解weex内核原理 https://zhuanlan.zhihu.com/p/71064826





转载本站文章《Weex原理及架构剖析》,
请注明出处:https://www.zhoulujun.cn/html/webfront/AppDev/Weex/8495.html

文从内核角度切入,为大家带来Weex技术演进之路的分享。

内核挑战

随着Weex业务规模的扩大和业务覆盖场景的丰富,Weex 不仅在性能稳定性上面临越来越大的挑战,在安全隔离方面,也遇到前所未有的风险。

性能方面:例如,去年的“双11”和今年“双11”主会场规模对比,去年整个会场的JS Bundle大小控制在250K以内,今年主会场页面平均达到500K+,业务复杂度增加了接近2倍,Weex 的加载性能跟JS bundle 的大小基本成正相关;

稳定性方面:业务场景覆盖面的提升,从原来的偏展示的场景到偏交互场景的业务,以及一些常规业务的接入;新的业务场景,必然导致新的稳定性方面的挑战,事实也如此;

富交互:引入Gcanvas、AR/VR等富交互场景,对Weex js-native的通信效率要求极高;

安全性:旧引擎的安全漏洞的问题,以及业务之间存在相互污染,无法做到安全隔离的问题;

证书问题:Yoga引擎的证书授权问题;

内核技术演进

从三个方面来阐述Weex 在内核重要方向的演进:JS引擎、Layout 引擎、WeexCore架构的演进;

JS引擎: 我们的目标是更快、更稳定、更安全、更小;其一:我们投入大量资源在JS引擎的优化上,从JS引擎的替换,由原来旧版本的V8 换成最新版本JavaScriptCore;其二:我们开创性地将JS Runtime 运行于独立的进程里,不仅保证主进程的稳定性,而且加入了智能恢复的能力;其三:重新考虑Weex 业务隔离的安全问题,开发设计了多Context 隔离的方案,保证避免业务间互相污染;其四:瘦身,包的精简;

Layout引擎:Weex项目成立以来,我们一直借用的Facebook的Yoga项目作为我们的布局引擎,但是Layout引擎对于Weex 项目又是如此重要,所以,我们今年10月份开始计划开发全新的Layout引擎开发的项目,来替换yoga引擎。第一,Layout 引擎作为核心模块,我们希望去主导演进的路线; 第二,Facebook的证书风险不能回避;所以我们决定重新开发自己的Layout 引擎,并争取做到更高性能,支持更多布局方式;

WeexCore架构:今年我们讨论最多的就是Weex 后续如何演进,在性能稳定性方面如何做的更优,在复杂业务的支持方面如何做的更好。WeexCore 首先是高性能的,用以满足更复杂场景业务开发,以及提升业务开发体验;其次是一个跨平台的内核,从DSL的跨平台到内核的跨平台。

JS引擎技术

众所周知,JS 引擎至于Weex至关重要,是Weex 最重要的一个核心模块,2017年,我们在JS 引擎的投入也是非常大:

  • 2017-3月~2017-7月:对最新版本的V8和最新版本的JavaScriptCore 做来全面的profile,让profile数据告诉我们去选择哪个引擎作为Weex新一代的JS 引擎。经过4个月的努力,终于将最新版本的JavaScriptCore 在手机淘宝正式版本上线,同时Weex也是第一个将JavaScriptCore引擎(javascriptcore引擎apple维护的,很少在android平台商业化过)集成到手机淘宝这样体量的App中,中间遇到的兼容性的问题也是我们最大的挑战。最终性能提升还是比较明显的,手淘上Weex整体业务首屏加载时间提高了40%+,并全面支持ES6特性;

  • 2017-7月~2017-10月:新版本的JavaScriptCore 上线以后,Weex的稳定性native crash 占比5%左右,按照手淘的稳定性要求(<1%)还是有比较大的差距,这个将是我们2017年双十一前最大的挑战。当时Weex稳定性小组的同学出于焦虑中,随着双十一临近,不断有新Weex 业务上线,伴随着冒出一些的兼容性的问题出来,始终看不到收敛的趋势。一方面,我们正向地去解决这些适配的问题,另一方面,我们也讨论如何彻底地解决JS引擎的稳定性的问题;后来,我们想到将JS 引擎独立运行到单独的进程里去,这个方案带来最大的好处,就是Weex 业务的crash 不会影响主程序的稳定性;这个方案也成了双十一Weex稳定性保障的救命稻草。最终这个方案在10月份前正式上线,效果非常明显,Weex 引起的native crash占比一下子从5%下降到0.5%左右。

  • 2017~11月~至今:双十一之后,JS 引擎项目主要在做两个事情,一个Weex安全隔离方案,另一个是包精简优化方案;Weex安全隔离方案主要解决页面隔离的问题,双十一当天也遇到一个非常严重的全局污染的案例,某个业务不小心污染了全局对象,导致所有的Rax的页面出现白屏的问题;针对这些案例,我们重新设计了Weex 安全隔离的方案,目前安全隔离方案已经内部灰度中,预计2月份正式社区发布;

    包精简优化方案:主要解决Weex sdk集成了最新版本的JavaScriptCore以后,包大小增大一倍的问题(4.2M左右),包的增大直接增大了App接入的门槛,特别是对包大小非常敏感的App。目前同步一下信息:精简优化方案目前也基本开发完毕,预计可以减少到2.6M左右,预计也是2月份上线;

独立进程化

问题

  1. 同一个进程中,与主App存在资源竞争,尤其是内存问题比较突出,JavaScriptCore虽然执行性能提升了,但对内存的消耗也同时增大不少,所以替换成JSC以后,Weex的内存问题导致Crash也明显上升;

  2. 独立进程的方案本身比较Hack,再加上Android生态的碎片化,开发过程中也遇到很多适配问题,比如在某些机型上独立进程拉不起来,导致业务渲染失败;

  3. JavaScriptCoe引擎本身对android平台适配比较差,没有比较大体量的App在线上应用过;

优势

  1. 进程独立以后,完全和主App的进程隔离,避免了进程资源竞争导致crash的问题,Weex的crash也不会引起主进程的crash;

  2. Weex 原有的三个线程架构,JS 线程任务被并行成两个,JS独立的进程和原来JS线程,整体增强了JS任务执行的并发性,抵消了方案本身的IPC通信的性能损耗;

  3. 独立进程后,我们加入了自修复的能力,增强了JS Runtime进程的自动重置功能,解决JS Runtime 异常后的无法自动恢复的问题,极大地保障业务的稳定性;

SandBox机制

Weex 原有的设计,所有Weex页面包括JSFrameWork 都是运行在同一个JS Context里,并在JS层面,对全局的JS 变量做了freeze操作,防止被其他业务页面污染。这个设计主要还是出于高性能和安全性的综合考量。

2017年双十一出现的全局污染的问题,让我们重新思考Weex Context的安全隔离的方案,安全稳定高于一切。经过新的讨论后,我们决定针对每个Weex页面都创建一个JS Context 作为独立的运行环境,页面依赖的全局对象由Global Contex统一生层并传递给每个页面的Contex;传输的过程,我们做了两个非常重要的操作:

1)对传输的对象做freeze操作;

2)在javaScript引擎层面,通过native的SetPrototype接口切断原型链的关系;这样就彻底解决了页面间互相污染的问题。该方案预计2月份正式上线。

Layout 引擎

全新的Layout引擎参考了 Google的FlexLayout的算法流程,重新实现了Weex的 Flex布局,目前性能和功能方面基本和yoga保持一致,后续会做一些性能优化。至于未来如何演进,团队同学讨论几个关键的步骤:

  1. 自主开发全新的高性能的跨平台Layout引擎,统一由C++实现,IOS/android 两端复用同一套代码;

  2. 扩展更多的布局方式,比如Gird布局、Absolute布局等

  3. 编译器或服务端做预布局,提升端测的布局效率等;

该方案预计2月份正式上线。

WeexCore 架构升级

Weex 作为一个跨平台的开发框架,在Android/ IOS/HTML 三端实现跨平台一致性非常重要。目前Weex 核心渲染流程分平台实现,不仅多人维护导致不可避免的逻辑实现差异,而且对于后续新平台扩展成本也非常高(核心渲染流程需要重新实现)。因此,想到抽象统一Weex 核心解析渲染流程,通过C + + 语言实现,实现 ios、android 平台核心逻辑统一,不仅可以增强平台间的一致性,降低维护成本,以及扩展平台的成本。通过C+ +代码执行效率要高于JAVA,同时还可提高Android端的代码执行性能。

  1. 提供标准的Weex Dom API Layer,简化DSL的接入成本,将大部分JSFramework native化;

  2. 抽象Weex平台无关的、核心的处理逻辑,android和IOS的porting层尽量做薄,一方面提高代码的复用率,另一方面降低新平台的扩展成本;

  3. 架构设计上的高可用,通用的模块可插拔,例如JS engine 模块和Layout engine模块能低成本地切换;

  4. 核心技术模块比如JS engine 等能标准化输出,服务更多的业务场景;

(本文作者饮源,阿里巴巴技术专家)