weex

背景

  • 开发成本大,IOS, 安卓,前端 需要三份代码

  • 安卓和ios 发版限制导致无法响应快速迭代的业务需求

跨平台解决方案

  • H5, Hybrid 开发模式,通过桥协议(jsBridge)实现双向通信的通道

  • weex,React Native,flutter 跨平台解决方案

优缺点

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

优点:

  • 该方案提升开发效率

  • 能够快速迭代业务需求

  • 满足了跨端的需求

缺点:

  • 前端H5的性能和客户端的性能相差甚远

weex & react-native & flutter

优点:

  • 同时app在终端的运行体验不输native app

  • 即可以保证快速响应需求,又可以保证用户体验

  • 适合人力成本上有困难的团队

缺点:

  • 额外的学习成本

  • 在性能上,原生还是更胜一筹

  • weex的社区资料少,不完善遇到问题不好排查定位,官方文档质量不高,维护不及时

  • flutter 还需要额外的学习dart语言,需要对英文有一定的了解,问题解决方案偏向于英文

weex

那么WEEX是如何实现的?

本质来说,WEEX是用客户端 Native 的能力,去做了部分浏览器(webview)的工作

weex 工作流

1
2
3
4
5
6
7
8
9
+--------------+
| js bundle | 服务器
+--------------+
| 下载
+--------------+
| js 执行环境 | 客户侧
| weex Bridge |
| 渲染引擎 |
+--------------+
  • 前端开发可以写熟悉vue语法的单文件,然后打包成出来一份dist —— JS Bundle,然后部署到服务器上

  • 客户端打开某一个页面,通过网络下载JS Bundle,然后在客户端本地执行该JS Bundle

  • 客户端提供了JS的执行引擎(ios:JSCore;安卓:v8)用于执行远程加载到JS Bundle

  • JS执行引擎执行JS Bundle,和浏览器的过程类似,JS Bundle 的代码被执行,生成VNode

  • 树进行patch,找出最小操作DOM节点的操作,把对DOM节点的操作转变为Native DOM API, 调用WXBridge 进行通信

  • WXBridge将渲染指令分发到native(Andorid、iOS)渲染引擎,由native渲染引擎完成最终的页面渲染

页面渲染并不是像H5方案一样使用浏览器的渲染能力,而是原生渲染,所以本质上渲染出来的页面就是一个native页面

详细过程

生成 JS bundle

  • JS bundle 是前端同学写好代码后打包出来的dist

  • 前端同学可以在.vue 的单文件中,写<template>,<style>和<script>标签,然后把这些标签转换为JS Bundle用于部署在服务端,之后客户端会去请求这些JS Bundle

WEEX SDK初始化

weex在真正打开一个页面之前,会先做一些准备的初始化工作,weex为了提高 Native 性能,做了很多优化的工作。会把业务代码和 vue.js 这类的依赖包分开打包

  • 初始化 js的执行环境,这个执行环境安卓上采用 v8 引擎,IOS 上,则是客户端自带的 js core

  • 加载weex-vue-framework 的代码,weex-vue-framework 向原生端发送渲染指令,最终渲染生成的是原生组件而非dom,weex 把weex-vue-framework 这类框架依赖内置到了SDK中,客户端访问Weex页面时,只会网络请求JS Bundle,所以就减少了JS Bundle的体积

  • 初始化WXBridge,主要通过 callJS 和 callNative 两个核心的方法,实现 js 代码和客户端代码双向通信

创建 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的增删改查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// VNode
{
tag: 'div',
children: [{
tag: 'text',
data: {
staticClass: 'set'
},
context: {
$options: {
style: {
freestyle: {
textAlign: 'center'
}
}
}
},
children: [{
tag: '',
text: 'Hello World!'
}]
}]
}
  • 生成了VNode之后,接下来需要将VNode同步到真实的Dom之上,该过程在 Vue 中被称为patch

  • 在执行 patch 之前的过程都是 Web 和 Weex 通用的,后面因为客户端没有对 DOM 增删改查的API,所以这些更新的操作,需要经过weex-vue-framework的处理,统统映射为客户端的Native DOM API

发送渲染指令

  • weex终端的执行引擎在执行到Native DOM API后,WXBridge将Native DOM API转化为Platform API

  • Platform API 是 Weex SDK 中原生模块提供的,不是 js 中方法,也不是浏览器中的接口,是 Weex 封装的一系列方法

1
2
3
4
5
6
7
8
9
10
11
+--------------+
| js 执行环境 |
+--------------+
↓ Native DOM API
+--------------+
+ weex Bridge |
+--------------+
↓ Platform API
+--------------+
| 渲染引擎 |
+--------------+

开发

  • 参照官网配置项目工程化脚手架

  • 配置基本的 webpack 相关 loader 和 plugin

  • 开发阶段,基本上是写 vue 代码(基于 vue 框架开发)template, style, script

  • 开发阶段,注意官方文档(文档存在缺陷不可全信),编写样式不要主观的按照前端的思路理解,要看weex支持什么写法和属性等,谨记前端对的在weex中不一定对

  • 开发完成将打包的 bundle 上传到 cdn,原生开发引入加载并渲染页面

调试技巧

  • 前期开发阶段,主要是在 chrome + Weex Playground 即可

  • 或者让原生开发打包一个 app ,通过输入本地 url 来加载展示(或者让原生添加 哆啦 A 梦 助手)

  • 后期上线 pro 或是 uat 抓包调试接口数据

返回
顶部