Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

对无线电商动态化方案的思考(二) #14

Open
Jinjiang opened this issue Nov 18, 2015 · 30 comments
Open

对无线电商动态化方案的思考(二) #14

Jinjiang opened this issue Nov 18, 2015 · 30 comments

Comments

@Jinjiang
Copy link

上一篇谈到了我对无线电商动态化的理解,并简单提到了我们自己提出的技术方案:Weex,今天就来详细介绍一下 Weex

一句话介绍

Weex 是一款轻量级的移动端跨平台动态性技术解决方案!

几个特点

轻量

体积小巧,语法简单,方便上手

可扩展

业务方可自行横向定制 native 组件和 API

高性能

快速加载,快速渲染,体验流畅

其它

  • 拥抱标准:基于 Web 标准设计语法
  • 响应式界面: 通过简单的模板数据绑定轻松解决数据和视图的同步关联问题
  • 多端统一:iOS、Android、HTML5 多端效果一致,撰写一次就可以轻松达到跨平台的一致性,无需针对多套平台单独开发,省时省力
  • 复杂逻辑描述:动态性不只体现在展示效果的动态性上,更体现在可以实时调整复杂的数据处理方式和逻辑控制方式
  • 组件化:组件之间通过 webcomponents 的设计完美的隔离,并可以通过特定的方式进行数据和事件的传递
  • 生态&链路:我们为 Weex 的开发者和使用者在不同维度上提供了各式各样的工具和平台,包括代码打包工具、开发者调试工具、部署平台、Playground、经典案例、入门指南和详尽的文档等。你不是从零开始,你也不是一个人在战斗!

如何工作

1. 本地组件开发

首先,我们像开发 webcomponents 一样,把一个组件分成 <template><style><script> 三部分,刚好对应一个组件的界面结构、界面样式、数据&逻辑。

components

图:组件化开发思维和书写方式

细节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 识别的,我们要想办法让这些代码可运行。所以我们同时做了三件事:

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

所以紧接着第二步,就是用 transformer 对代码进行转换,变成客户端可运行的 JavaScript 代码

transformer

图:本地开发时的 Weex Transformer 工作原理

其实本地开发还有一点很重要,就是把复杂的界面通过组件化的方式进行分解,并合理的建立组件之间的组合和调用关系。

最终,我们把简单组件组合成复杂的界面,并通过 transformer 打包成一个完整的程序包 (主体是一段 JavaScript 代码)

细节2:由于 Weex 组件的开发和 Web 组件的开发非常接近,但是对标准的支持范围和一些细节是有不同之处的,我们会贴心的在 transformer 里加入了一些友情提醒,帮助大家回避常犯的书写错误。

2. 客户端渲染

上一节已经提到了,我们在客户端会运行一个 JavaScript 引擎并且有 JS Bridge 通信机制。这里再介绍具体一些:

native 渲染和 JavaScript 引擎之间,主要进行三类通信:

  1. 界面渲染,单向 (JS -> native):这毫无疑问,JavaScript 引擎需要把界面的结构和样式告诉 native 端,这样我们才能得到 native 级别的终极界面效果
  2. 事件绑定与触发,双向:在我们的客户端技术方案中,native 端只负责界面渲染和非常薄的事件触发层,事件的逻辑处理都会放在 JavaScript,这样我们就具备了复杂数据处理和逻辑控制的动态性可能。JS 告诉 native 需要监听的交互行为,而当用户产生对应的交互行为时,native 端会把交互信息回传给 JS
  3. 对外的数据/信息请求与响应,双向:JS 引擎在处理特殊逻辑时,难免需要向服务器请求数据、或请求本地的系统信息和用户信息、或调用 native 的某个功能,这个时候也会通过 JS Bridge 进行请求,native 收到这些请求之后,也会在必要的情况下通过 JS Bridge 把信息回传给 JS 引擎

runtime

图:客户端运行时的 JS 引擎和 native 之间的通信

再加上外层对 Weex 实例的管理,整套机制就可以顺畅的工作起来了

细节3:native 端渲染的时候,我们以图片和文字的形态为主,并大量依赖了标准的 CSS 样式进行细节的渲染

细节4:我们把框架层面的 JS 代码全部提前放在了客户端本地,并提前运行做好准备。这样本地生产的 JavaScript 是非常小的,网络传输的代价也非常低,而在客户端运行的初始化成本也非常低。整条链路都和界面打开速度息息相关

细节5:我们在 JS 处理界面逻辑的过程中采取了数据监听+依赖收集的策略,既没有通过脏检查,也没有通过全量 diff Virtual DOM 树的方式,因为通常在移动端,数据变更都是非常小量的,经过我们的实践,这套方案完全可以应付移动端日常的动态性界面需求

virtualdom

图: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 版本。然后发布这样的一个页面。

html5

图:HTML5 浏览器端的架构实现

细节9:我们能够同构 HTML5 版本和 native 版本,主要归功于我们在 JS Bridge、组件定义、API 定义方面的高度抽象——当然 HTML5 的版本在性能和体验上确实有一定的劣势,并不是最理想化的效果,所以核心的主战场还是客户端,这也和目前的移动互联网的形态相吻合

5. 周边

为了方便 native 界面的调试,我们还提供了配套的开发者工具,稍后会有更多介绍,同时我们的上层配套可视化编辑器和装修工具,也在紧张的研发当中。

综上所述,整个 Weex 的工作原理大致可以用一张图来表述:

workflow

## 回看 Weex 的几个特点 ### 轻量

我们致力于把开发体验、网络传输的大小、运行时的开销控制做到极致,并且尽可能的降低多端适配和优雅降级的成本

横向可扩展

我们对组件的定义和业务功能预留了很好的横向可扩展能力,这也业务方可以自由定制属于自己的 native 组件和 API,从而在后期可以通过实时发布不同的程序包来进行动态化控制。同时也因为它的横向可扩展性,Weex 的核心可以非常小,非常易于融入现有的无线技术体系

高性能

我们在网络传输、实例初始化、JS 运算、native 渲染能力等方面做了非常针对性且深入的优化,尤其是针对中低端安卓机,不论是加载时间还是运行时的流畅度,都比之前的方案有质的飞跃。我们对 CPU、内存、帧率、首屏渲染时间等核心性能指标也一直保持高度的关注,也建立了相应的线上监控和数据统计机制。而更多可优化的空间和方案我们还在不断的进行优化尝试。

下图是今天凌晨旧金山 QCon 上 Weex 技术方案的首次公开分享中的一页性能表现对比图,大家可以感受一下:

总结

这就是 Weex,如上一篇文章所介绍的:

  • 致力于移动端
  • 能够充分调度 native 的能力
  • 能够充分解决和回避性能瓶颈
  • 能够灵活扩展
  • 能够多端统一
  • 能够优雅“降级”到 HTML5
  • 能够保持较低的开发成本
  • 能够快速迭代
  • 能够轻量实时发布
  • 能够融入现有的 native 技术体系
  • 能够工程化管理和监控

目前 Weex 还在努力达到更高的性能、更高的扩展性、更低的开发成本、更完整的生态和工具链,也同时尝试接入更多的业务,体现出它的更大的价值。已经有很多业务方迫不及待的在和我们主动取得联系了,未来我们希望 Weex 能够逐步在集团内开放试用,并最终走向开源。

另外整个技术方案还有很多值得分享的东西,比如 transformer 的实现、组件和 API 的设计思路等,我们会再做针对性的分享和介绍

(马上更新第三篇ing)

继续阅读:

@zzbo
Copy link

zzbo commented Nov 18, 2015

当时以为是讲react呢。

@wssgcg1213
Copy link

很有诚意 期待WEEX的开源

@myheartwillgoon
Copy link

给数学老师点个赞!!

@Gaohaoyang
Copy link

给跪了,真牛逼。

越看越兴奋!

@pfan123
Copy link

pfan123 commented Nov 18, 2015

good

@KavinHan
Copy link

支持~期待开源+1

@miniflycn
Copy link

作为业务狗,的确有些惆怅。我们团队其实早在年初就开始实践这件事情了,可惜完全没有时间去实现全端同构的构想。🐶

@GavinHans
Copy link

very good .

@ouvens
Copy link

ouvens commented Nov 19, 2015

最近一直在炒webcomponent,并基于其思想自己设计框架,但是很多人并没有理解webcomponent的规范的含义和未来的规范趋势,只是借鉴了它的设计思想造自己的轮子而已,设计的时候可以更注重下什么是规范~

@RubyLouvre
Copy link

HTML与JS规范不是向来被大家践踏的吗?!而且web components是谷歌自己率先提出来的,而更早的由微软提出的html components规范其他厂商都不想支持,没有理由让微软去支持它

@yolio2003
Copy link

@ouvens 那规范自己快挂了

@iphone-andy
Copy link

听起来很牛逼的样子

@happypeter
Copy link

“三端大统一”的时代,是不是 ios 和 andriod 开发者都要考虑转学 js 了?

@floraluo
Copy link

看不明白这是啥子,是说以后开发app都不用java和ObjectC了吗?像cordova那样 暴露接口给js用吗????

@myheartwillgoon
Copy link

@floraluo 混合模式开发,纯native模式业务更新不方便,纯js体验没native好,外部通用框架对自己的业务太重,按灵活性与体验感寻求适合自己业务的平衡点.

@daemonchen
Copy link

mark

@CodeDaraW
Copy link

最后一个图表,新技能get

@Grainspring
Copy link

关注Virtual DOM与native Android/IOS View的关系,有丰富的ListView支持嘛。还有JS引擎运行的线程与UI主线程是同一个嘛

@InsCake
Copy link

InsCake commented Nov 23, 2015

你这个图是ipad pro画的吗?

@xiekw2010
Copy link

考虑过react的三端统一吗?我意思react component在最上层有一套通用的组件,供web,iOS,android调用

@Jinjiang
Copy link
Author

@InsCake FiftyThree 我觉得 Apple Pen 是抄他们的

@Jinjiang
Copy link
Author

@xiekw2010 之前也考虑过,这是个上层 DSL 的设计问题,最近已经有同学在跟我们探讨这个问题了,不过总体上我们对 JSX 的设计还是持观望态度

@qqqzhch
Copy link

qqqzhch commented Dec 12, 2015

回避性能瓶颈!!!!说的太好了
现在很多人一说性能优化就要和某个性能瓶颈做死磕,
海能写一堆方法论出来
BUT客户端千变万化的环境,死磕到猴年马月才能解决完呢

@zhangchunsheng
Copy link

我们在开发App时,发现运营需求越来越多,配置越来越灵活,选择React是唯一解决方案,期待Weex开源

@dingyiming
Copy link

期待WEEX开源

@smileEvday
Copy link

Mark 一下,hybird开发又向前迈进了一步

@54lazycat
Copy link

渲染时间300ms。这个真的不要紧吗?

@Jinjiang
Copy link
Author

Jinjiang commented May 4, 2016

@54lazycat 会比纯 native 慢一些 (纯 native 一般会在 100ms 左右),但是带来的好处是很多的,比如灵活性和低发布约束等。当然这里在未来也许还有优化空间。

@pinkski
Copy link

pinkski commented Dec 9, 2016

weex怎么实现Component暴露给js的呢,就像RN的通信机制依赖了宏RCT_EXPORT()

@gongph
Copy link

gongph commented Jan 24, 2017

期待 weex 开源。最后一公里加油!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests