select.md 23.7 KB
Newer Older
W
x  
wanganxp 已提交
1
# 跨平台开发框架比较
W
wanganxp 已提交
2

W
x  
wanganxp 已提交
3 4 5
App跨平台框架历史悠久,从cordova、react native、flutter,直到最近的uni-app x。江山代有才人出,每个都试图颠覆原生,但过去却一直未成功。

过去的问题到底在哪里?uni-app x为什么和过去那些方案不一样?
W
wanganxp 已提交
6 7 8

我们先捋一捋各种技术路线,看看这些跨平台开发框架为什么不如原生应用。

W
x  
wanganxp 已提交
9 10 11 12 13 14 15 16 17
|逻辑层		|渲染层					|类型		|代表作																|
|--				|--							|--			|--																		|
|webview	|webview				|弱类型	|5+App、cordova												|
|js引擎		|webview				|弱类型	|uni-app app-vue、小程序(dount)			|
|js引擎		|原生渲染				|弱类型	|react native、uni-app app-nvue、weex	|
|dart引擎	|flutter渲染引擎|强类型	|flutter															|
|js引擎		|flutter渲染引擎|弱类型	|微信skyline、webF、ArkUI-x						|
|kotlin		|原生渲染				|强类型	|uni-app x														|
|kotlin		|原生渲染				|强类型	|原生应用															|
W
wanganxp 已提交
18

W
x  
wanganxp 已提交
19 20
上面的表格,除了行尾的原生应用外,各个跨平台框架按出现时间排序,可以看到跨平台框架是如何演进的。

W
x  
wanganxp 已提交
21
上表中,uni-app x和原生应用是一样的,逻辑层和渲染层都是原生,都是强类型;而其他跨平台框架或者在逻辑层、或者在渲染层与原生不一致。
W
wanganxp 已提交
22

W
wanganxp 已提交
23
webview与原生的差距已经是业内常识了,启动慢、渲染慢、内存占用高。这块本文不再详述。
W
wanganxp 已提交
24 25 26

但那些非web-view的框架到底哪里不如原生?

W
x  
wanganxp 已提交
27
## js+原生渲染
W
wanganxp 已提交
28 29 30
react native等抛弃webview,改由原生渲染的跨平台方案,2014年就推出了。如今手机硬件也越来越好了,为什么性能还达不到原生?

js+原生渲染的方案问题如下:
W
x  
wanganxp 已提交
31 32 33 34 35 36 37 38
### 1. js引擎慢,启动速度和运行速度都弱于原生

所以很多开发者即便使用这类方案,首页也还是原生来写。

React Native的Hermes引擎和华为,提供了js编译为字节码的方案,这是一种空间换时间的方案,启动速度有了一定优化,但仍然比不过原生。

弱类型在编译期能优化的有限,还是需要一个运行时来跑,而不能像强类型那样直接深入底层。

W
x  
wanganxp 已提交
39
以数字运算为例,js的number运算确实比强类型的int慢,内存开销也更大。
W
x  
wanganxp 已提交
40 41 42 43 44 45 46 47 48 49 50

### 2. js语言与原生之间通信卡顿

每个语言有自己的内存空间,跨语言通信都有折损,每次通信几十到几百毫秒不等,视手机当时的状态。一旦频繁通信,就会明显卡顿。

逻辑层的js,即要和原生渲染层通信,还要和原生API通信:

- 2.1 js与原生ui通信

举个简单的场景例子,在js里监听滚动,根据滚动变化实时调整界面上某些元素的高度变化。
这个问题能难倒一大批跨平台开发框架。
D
DCloud_LXH 已提交
51

W
x  
wanganxp 已提交
52 53 54
如果全部在webview里,js操作ui还好一些,所以uni-app的app-vue里的renderjs操作UI性能高,就是这个道理。同理还有微信小程序的wsx。

虽然小程序和uni-app都是js,但实际上逻辑层在独立js引擎里,通过原生桥来控制web-view,通信成本很高。
D
DCloud_LXH 已提交
55

W
x  
wanganxp 已提交
56 57
weex提供了bindingx技术,这是一种弱编程,渲染层预先定义了一些操作UI的方式,调用时全部在渲染层运行,不会来回与逻辑层通信。
但这种预定义方式的适应面有限,无法做到在js里高性能、自由的操作所有UI。
D
DCloud_LXH 已提交
58

W
x  
wanganxp 已提交
59 60 61
- 2.2 js操作原生api

操作系统和三方SDK的API都是原生的,js调用这些能力也需要跨语言通信。比如js调用原生的Storage或IO,数据较多时遍历的性能非常差。
D
DCloud_LXH 已提交
62

W
x  
wanganxp 已提交
63 64 65
当然在js API的封装上可以做些优化,比如微信的storage提供了wx.batchGetStorageSync这种批量读取的API,既然遍历性能差,那干脆一次性从原生读出来再传给js。

这也只能是无奈的方案,如果在遍历时想用js做什么判断就实现不了了,而且一次性读出很大的数据后传给js这一下,也需要通信时间。
W
wanganxp 已提交
66

W
x  
wanganxp 已提交
67
## flutter
W
wanganxp 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80
flutter2018年发布,第一次统一了逻辑层和渲染层,而且使用了强类型。

它没有使用原生渲染,而是使用由dart驱动的渲染引擎,这样逻辑层的dart代码操作UI时,再也没有延时了!bindingx、wxs这种补丁方案再也不需要了。

并且dart作为强类型,编译优化很好做,启动速度和运行速度都胜过js。

在这个开源项目下[https://gitcode.net/dcloud/test-cross/-/tree/master/test_flutter_slider_100](https://gitcode.net/dcloud/test-cross/-/tree/master/test_flutter_slider_100),提供了一个flutter编写的100个slider同时滑动的示例,
项目下有源码也有打包好apk,可以直接安装体验。

100个slider同时滑动,非常考验逻辑和UI的通信。如果在webview内部,html和js写100个这样的slider,在新的手机上表现也还ok。但在小程序和react native这种逻辑和UI分离的模式下,100个slider是灾难。

下载apk后可以看到dart操作flutter的UI真的没有通信折损,100个slider的拖动非常流畅。

D
DCloud_LXH 已提交
81
<video id="video" preload="none" controls="controls" width="185px" height="400px" poster="https://web-ext-storage.dcloud.net.cn/doc/flutter-slider-poster.png" src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/test-cross/flutter-slider.mp4"></video>
W
wanganxp 已提交
82

W
x  
wanganxp 已提交
83
flutter看起来很完美。但为什么也没有成为主流呢?很多大厂兴奋的引入后为何又不再扩大使用范围呢?
W
wanganxp 已提交
84

W
x  
wanganxp 已提交
85
### 1. dart与原生API的通信
W
wanganxp 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98 99
别忘了上面2.2提到的原生API通信。flutter虽然在逻辑层和渲染层都是dart,但要调用原生API时,还是要通信。

操作系统和三方SDK的API是原生的,让dart调用需要做一层封装,又落到了跨语言通信的坑里。

[https://gitcode.net/dcloud/test_flutter_message_channel](https://gitcode.net/dcloud/test_flutter_message_channel)这是一个开源测试项目,来测试原生的claas数据与dart的通信耗时。

项目里面有源码,大家可自行编译;根目录有打包好的apk,可直接安装体验。

这个项目首先在kotlin中构建了包含不同数据量的class,传递到dart然后渲染在界面上,并且再写回到原生层。

有0.1k和1k两种数据量(点击界面上的1k数字可切换),有读和读并写2个按钮,各自循环1000次。

以下截图的测试环境是华为mate 30 5G,麒麟990。手机上所有进程杀掉。如下图:
- 1k数据从原生读到dart并渲染
W
x  
wanganxp 已提交
100

D
DCloud_LXH 已提交
101
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/test-cross/flutter_1k_read.jpeg)#{.zooming height="400px"}
W
wanganxp 已提交
102
- 1k数据从原生读到dart并渲染再写回
W
x  
wanganxp 已提交
103

D
DCloud_LXH 已提交
104
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/test-cross/flutter_1k_readwrite.jpeg)#{.zooming height="400px"}
W
wanganxp 已提交
105
- 0.1k数据从原生读到dart并渲染
W
x  
wanganxp 已提交
106

D
DCloud_LXH 已提交
107
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/test-cross/flutter_0.1k_read.jpeg)#{.zooming height="400px"}
W
wanganxp 已提交
108
- 0.1k数据从原生读到dart并渲染再写回
W
x  
wanganxp 已提交
109

D
DCloud_LXH 已提交
110
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/test-cross/flutter_0.1k_readwrite.jpeg)#{.zooming height="400px"}
W
wanganxp 已提交
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140

通信损耗非常明显。数据量从1k降低到0.1k时,通信时间并没有减少10倍,这是因为通信耗时有一个基础线,数据再小也降不下去。

dart并不能直接调用kotlin的class,只能先序列化成字符串,把字符串数据从原生传到dart,然后在dart层再重新构造。

当然也可以在原生层为dart封装API时提供wx.batchGetStorageSync这类批处理API,把数据一次读好再给dart,但这种又会遇到灵活性问题。

而在uni-app x中,这种跨语言通信是不存在的,不需要序列化,因为uni-app x使用的编程语言uts,在android上就编译为了kotlin,它可以直接调用kotlin的class而无需通信和封装。示例如下,具体uni-app x的原理后续章节会专题介绍。

```ts
<template>
</template>
<script lang="uts">
import Build from 'android.os.Build';
export default {
	onLoad() {
		console.log(Build.MODEL); //uts可以直接导入并使用原生对象,不需要封装,没有跨语言通信折损
	}
}
</script>
```

再分享一个知识:

很多人都知道iPhone上跨平台框架的应用,表现比android好。但大多数人只知道是因为iPhone的硬件好。

其实还有一个重要原因,iOS的jscore是c写的,OS的API及渲染层也都是ObjectC,js调用原生时,某些类型可以做共享内存的优化。但复杂对象也还是无法直接丢一个指针过去共享使用内存。

而android,不管java还是kotlin,他们和v8、dart通信仍然需要跨语言通信。

W
x  
wanganxp 已提交
141
### 2. flutter渲染和原生渲染的并存问题
W
wanganxp 已提交
142 143 144 145 146

flutter的自渲染引擎,在技术上是不错的。但在生态兼容上有问题。

很多三方软件和SDK是原生的,原生渲染和flutter自渲染并存时,问题很多。

W
x  
wanganxp 已提交
147
flutter开发者都知道的一个常见坑是输入法,因为输入法是典型的原生UI,它和flutter自绘UI并存时各种兼容问题,输入框被遮挡、窗体resize适应,输入法有很多种,很难适配。
W
wanganxp 已提交
148 149 150

混合渲染,还有信息流广告、map、图表、动画等很多三方sdk涉及。这个时候内存占用高、渲染帧率下降、不同渲染方式字体不一致、暗黑主题不一致、国际化、无障碍、UI自动化测试,各种不一致。。。

W
x  
wanganxp 已提交
151 152
这里没有提供开源示例,因为flutter官方是承认这个问题的,它提供了2种方式:混合集成模式和虚拟显示模式模式。

W
x  
wanganxp 已提交
153 154 155
但在渲染速度、内存占用、版本兼容、键盘交互上都各自有各自的问题。
详见flutter官网:[https://docs.flutter.dev/platform-integration/android/platform-views#performance](https://docs.flutter.dev/platform-integration/android/platform-views#performance)
这个是中文翻译:[https://flutter.cn/docs/platform-integration/android/platform-views#performance](https://flutter.cn/docs/platform-integration/android/platform-views#performance)
W
wanganxp 已提交
156

W
x  
wanganxp 已提交
157
在各大App中,微信的小程序首页是为数不多的使用flutter UI的界面,已经上线1年以上。
W
wanganxp 已提交
158

W
x  
wanganxp 已提交
159
下面是微信8.0.44(此刻最新版),从微信的发现页面进入小程序首页。
W
x  
wanganxp 已提交
160

D
DCloud_LXH 已提交
161
<video id="video" preload="none" controls="controls" width="185px" height="400px" poster="https://web-ext-storage.dcloud.net.cn/doc/weixin_dark-poster.png" src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/test-cross/weixin_dark.mp4"></video>
W
x  
wanganxp 已提交
162 163 164 165 166 167

视频中手机切换暗黑主题后,这个UI却还是白的,而且flutter的父容器原生view已经变黑了,它又在黑底上绘制了一个白色界面,体验非常差。

这个小程序首页界面很简单,没有输入框,规避了混合渲染,点击搜索图标后又跳转到了黑色的原生渲染的界面里。

假使这个界面再内嵌一个原生的信息流SDK,那会看到白色UI中的信息流广告是黑底的,更无法接受。
W
wanganxp 已提交
168 169 170

当然这不是说flutter没法做暗黑主题,重启微信后这个界面会变黑。这里只是说明渲染引擎不一致带来的各种问题。

W
x  
wanganxp 已提交
171
> 注:如何识别一个界面是不是用flutter开发的?在手机设置的开发者选项里,有一个GPU呈现模式分析,flutter的UI不触发这个分析。且无法审查布局边界。
W
wanganxp 已提交
172 173 174 175 176

flutter的混合渲染的问题,在所有使用原生渲染的跨平台开发框架中都不存在,比如react native、weex、uni-app x。

总结下flutter:逻辑层和UI层交互没有通信折损,但逻辑层dart和原生api有通信成本,自绘UI和原生ui的混合渲染问题很多。

W
x  
wanganxp 已提交
177
## js+flutter渲染
W
wanganxp 已提交
178

W
x  
wanganxp 已提交
179
flutter除了上述提到的原生通信和混合渲染,还有3个问题:dart生态、热更新、以及比较难用的嵌套写法。
W
wanganxp 已提交
180

W
x  
wanganxp 已提交
181
一些厂商把flutter的dart引擎换成了js引擎,来解决上述3个问题。比如微信skyline、webF、ArkUI-x。
W
wanganxp 已提交
182

W
x  
wanganxp 已提交
183
其实这令人困惑。因为这又回到了react native和weex的老路了,只是把原生渲染换成了flutter渲染。
W
wanganxp 已提交
184

W
x  
wanganxp 已提交
185
flutter最大的优势是dart操作UI不需要通信,以及强类型。而改成js,操作UI再次需要通信,又需要js引擎。
W
wanganxp 已提交
186 187 188 189 190 191

为了解决js和flutter渲染层的通信问题,微信的skyline又推出了补丁技术worklet动画,让这部分代码运行在UI层。(当然微信的通信,除了跨语言,还有跨进程通信,会更明显)

这个项目[https://gitcode.net/dcloud/test-cross/-/tree/master/test_arkuix_slider_100](https://gitcode.net/dcloud/test-cross/-/tree/master/test_arkuix_slider_100)
使用ArkUI-x做了100个slider,大家可以看源码,下载apk体验,明显能看到由于逻辑层和UI层通信导致的卡顿。

D
DCloud_LXH 已提交
192
<video id="video" preload="none" controls="controls" width="185px" height="400px" poster="https://web-ext-storage.dcloud.net.cn/doc/arkui-x-slider-poster.png" src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/test-cross/arkui-x-slider.mp4"></video>
W
wanganxp 已提交
193 194 195

上述视频中,手指按下的那个slider,和其他通过数据通讯指挥跟随一起行动的99个slider,无法同步,并且界面掉帧。

W
x  
wanganxp 已提交
196
不过自渲染由于无法通过Android的开发者工具查看GPU呈现模式,所以无法从条状图直观反映出掉帧。
W
wanganxp 已提交
197

W
wanganxp 已提交
198 199
> 注意ArkUI-x不支持`Android8.0`以下的手机,不要找太老的手机测试。

W
wanganxp 已提交
200 201 202 203 204 205 206 207
很多人以为自渲染是王道,但其实自渲染是坑。因为flutter的UI还会带来混合渲染问题。

也就是说,js+flutter渲染,和js+原生渲染,这2个方案相比,都是js弱类型、都有逻辑层和渲染层的通信问题、都有原生API通信问题,而js+flutter还多了一个混合渲染问题。

可能有的同学会说,原生渲染很难在iOS、Android双端一致,自渲染没有这个问题。

但其实完全可以双端一致,如果你使用某个原生渲染框架遇到不一致问题,那只是这个框架厂商做的不好而已。

W
x  
wanganxp 已提交
208 209
是的,很遗憾react native在跨端组件方面投入不足,官方连slider组件都没有,导致本次评测中未提供react native下slider-100的示例和视频。

W
x  
wanganxp 已提交
210
## uni-app x
W
wanganxp 已提交
211 212 213

2022年,uts语言发布。2023年,uni-app x发布。

W
x  
wanganxp 已提交
214
uts语言是基于typescript修改而来的强类型语言,编译到不同平台时有不同的输出:
W
wanganxp 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
- 编译到web,输出js
- 编译到Android,输出kotlin
- 编译到iOS,输出swift

而uni-app x,是基于uts语言重新开发了一遍uni-app的组件、API以及vue框架。

如下这段示例,前端的同学都很熟悉,但它在编译为Android App时,变成了一个纯的kotlin app,里面没有js引擎、没有flutter、没有webview,从逻辑层到UI层都是原生的。
```html
<template>
	<view class="content">
		<button @click="buttonClick">{{title}}</button>
	</view>
</template>

<script> //这里只能写uts
	export default {
		data() {
			return {
				title: "Hello world"
			}
		},
		onLoad() {
			console.log('onLoad')
		},
		methods: {
			buttonClick: function () {
				uni.showModal({
					"showCancel": false,
					"content": "点了按钮"
				})
			}
		}
	}
</script>

<style>
	.content {
		width: 750rpx;
		background-color: white;
	}
</style>
```

这听起来有点天方夜谭,很多人不信。DCloud不得不反复告诉大家,可以使用如下方式验证:
W
x  
wanganxp 已提交
259
- 在编译uni-app x项目时,在项目的unpackage目录下看看编译后生成的kt文件
W
wanganxp 已提交
260 261 262
- 解压打包后的apk,看看里面有没有js引擎或flutter引擎
- 手机端审查布局边界,看看渲染是不是原生的(flutter和webview都无法审查布局边界)

W
x  
wanganxp 已提交
263 264
但是开发者也不要误解之前的uni-app代码可以无缝迁移。
- 之前的js要改成uts。uts是强类型语言,上面的示例恰好类型都可以自动推导,不能推导的时候,需要用`:``as`声明和转换类型。
W
x  
wanganxp 已提交
265
- uni-app x支持css,但是css的子集,不影响开发者排版出所需的界面,但并非web的css全都兼容。
W
x  
wanganxp 已提交
266

W
wanganxp 已提交
267
了解了uni-app x的基本原理,我们来看下uni-app x下的100个slider效果怎么样。
W
wanganxp 已提交
268

W
wanganxp 已提交
269
项目[https://gitcode.net/dcloud/test-cross/-/tree/master/test_uniappx_slider_100](https://gitcode.net/dcloud/test-cross/-/tree/master/test_uniappx_slider_100)下有源码工程和编译好的apk。
W
wanganxp 已提交
270

W
wanganxp 已提交
271
如下视频,打开了GPU呈现模式,可以看到没有一条竖线突破那条红色的掉帧安全横线,也就是没有一帧掉帧。
W
wanganxp 已提交
272

D
DCloud_LXH 已提交
273
<video id="video" preload="none" controls="controls" width="185px" height="400px" poster="https://web-ext-storage.dcloud.net.cn/doc/uni-app-x-slider-poster.png" src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/test-cross/uni-app-x-slider.mp4"></video>
W
wanganxp 已提交
274

W
wanganxp 已提交
275
uni-app x在Android端,不管逻辑层、渲染层,都是kotlin,没有通信问题、没有混合渲染问题。不是达到了原生的性能,而是它本身就是原生应用,它和原生应用的性能没差别。
W
wanganxp 已提交
276 277 278

这也是其他跨平台开发框架做不到的。

W
wanganxp 已提交
279 280 281 282 283 284 285 286 287 288 289
uni-app x是一次大胆的技术突破,分享下DCloud选择这条技术路线的思路:

DCloud做了很多年跨平台开发,uni-app在web和小程序平台取得了很大的成功,不管规模大小的开发者都在使用;
但在app平台,大开发者只使用uni小程序sdk,中小开发者的app会整体使用。

究其原因,uni-app在web和小程序上,没有性能问题,直接编译为了js或wxml,uni-app只是换了一种跨平台的写法,不存在用uni-app开发比原生js或原生wxml性能差的说法。

但过去基于小程序架构的app端,性能确实不及原生开发。

那么App平台,为什么不能像web和小程序那样,直接编译为App平台的原生语言呢?

W
x  
wanganxp 已提交
290 291 292
**uni-app x,目标不是改进跨平台框架的性能,而是给原生应用提供一个跨平台的写法。**

这个思路的转换使得uni-app x超越了其他跨平台开发框架。
W
wanganxp 已提交
293

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
294
在Web端编译为js,在小程序端编译为wxml等,在Android端编译为kotlin。
W
wanganxp 已提交
295 296
每个平台都只是帮开发者换种一致的写法而已,运行的代码都是该平台原生的代码。

W
x  
wanganxp 已提交
297 298 299 300 301 302 303 304 305 306 307
然而在2年前,这条路线​有2个巨大的风险:
1. 从来没有人走通过
2. 即便能走通,工作量巨大

没有人确定这个产品可以做出来,DCloud内部争议也很多。

还好,经历了无数的困难和挑战,这个产品终于​面世了。

​换个写法写原生应用,还带来另一个好处。

同样业务功能的app,使用vue的写法,比手写纯原生快多了。也就是uni-app x对开发效率的提升不只是因为跨平台,单平台它的开发效率也更高。
W
wanganxp 已提交
308 309 310

其实google自己也知道原生开发写法太复杂,关于换种更高效的写法来写原生应用,他们的做法是推出了compose UI。

W
x  
wanganxp 已提交
311
不过遗憾的是这个方案引入了性能问题。我们专门测试使用compose UI做100个slider滑动的例子,流畅度也掉帧。
W
x  
wanganxp 已提交
312

W
wanganxp 已提交
313 314 315
源码见:[https://gitcode.net/dcloud/test-cross/-/tree/master/test_compose_ui_slider_100](https://gitcode.net/dcloud/test-cross/-/tree/master/test_compose_ui_slider_100)
项目下有打包后的apk可以直接安装体验。

W
x  
wanganxp 已提交
316
打开GPU呈现模式,可以看到compose ui的100个slider拖动时,大多数竖线都突破那条红色的掉帧安全横线,也就是掉帧严重。
W
wanganxp 已提交
317

D
DCloud_LXH 已提交
318
<video id="video" preload="none" controls="controls" width="185px" height="400px" poster="https://web-ext-storage.dcloud.net.cn/doc/compose-ui-slider-poster.png" src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/test-cross/compose-ui-slider.mp4"></video>
W
wanganxp 已提交
319

W
wanganxp 已提交
320
既然已经把不同开发框架的slider-100应用打包出来了,我们顺便也比较了不同框架下的包体积大小、内存占用:
W
wanganxp 已提交
321

W
wanganxp 已提交
322 323 324 325 326 327 328 329 330 331 332
|						|包体积(单位:M)	|内存占用(单位:Kb)|
|--					|--								|--									|
|flutter		|18								|141324.8						|
|ArtUI-x		|45.7							|133091.2						|
|uni-app x	|8.5							|105451.2						|
|compose ui	|4.4							|98575.2						|

包体积数据说明:
- 包含3个CPU架构:arm64、arm32、x86_64。
- flutter的代码都是编译为so文件,支持的cpu类型和包体积是等比关系,1个cpu最小需要6M体积,业务代码越多,cpu翻倍起来越多。
- ArtUI-x的业务代码虽然写在js里,但除了引用了flutter外还引用了js引擎,这些so库体积都不小且按cpu分类型翻倍。
W
x  
wanganxp 已提交
333
- uni-app x里主业务都在kotlin里,kotlin和Android x的兼容库占据了不少体积。局部如图片引用了so库,1个cpu最小需要7M体积。但由于so库小,增加了2个cpu类型只增加了不到1M。
W
wanganxp 已提交
334 335 336 337 338 339 340 341 342 343 344 345 346
- compose ui没有使用so库,体积裁剪也更彻底。
- uni-app x的常用模块并没有裁剪出去,比如slider100的例子其实没有用到图片,但图片使用的fesco的so库还是被打进去了。实际业务中不可能不用图片,所以实际业务中uni-app x并不会比compose ui体积大多少。

内存占用数据说明:
- 在页面中操作slider数次后停止,获取应用内存使用信息VmRSS: 进程当前占用物理内存的大小
- 表格中的内存数据是运行5次获取的值取平均值
- 自渲染会占据更多内存,如果还涉及混合渲染那内存占用更高

## 后记

跨语言通信、弱类型、混合渲染、包体积、内存占用,这些都是过去跨平台框架不如原生的地方。

这些问题在uni-app x都不存在,它只是换了一种写法的原生应用。
W
x  
wanganxp 已提交
347

W
x  
wanganxp 已提交
348 349 350 351 352 353 354 355
|代表作											|类型		|逻辑层与UI通信折损	|逻辑层与OS API通信折损	|混合渲染	|包体积																		|内存										|
|--													|--			|--							|--									|--				|--																				|--											|
|react native、nvue、weex		|弱类型	|有							|有									|无				|js引擎体积大且分CPU											|js引擎占用更多内存			|
|flutter										|强类型	|无							|有									|有				|flutter引擎体积大、业务代码变为so且分CPU	|flutter引擎占用更多内存|
|微信skyline、webF、ArkUI-x	|弱类型	|有							|有									|有				|js和flutter引擎体积大										|2个引擎占用更多内存		|
|uni-app x									|强类型	|无							|无									|无				|较小																			|较低										|
|原生应用										|强类型	|无							|无									|无				|较小																			|较低										|

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
356
当然,作为一个客观的分析,这里需要强调uni-app x刚刚面世,还有很多不成熟的地方。
W
x  
wanganxp 已提交
357 358 359 360 361 362

[需求墙](https://vote.dcloud.net.cn/#/?name=uni-app%20x)里都是uni-app x该做还未做的。也欢迎大家投票​。

另外,原生Android中一个界面不能有太多元素,否则性能会拉胯。flutter的自渲染和compose ui解决了这个问题。而原生中解决这个问题需要引入自绘机制来降低元素数量,这个在uni-app x里对应的是draw自绘API​。

uni-app x这个技术路线是产业真正需要的东西,随着产品的迭代完善,它能真正帮助开发者即提升开发效率又不牺牲性能。​
W
wanganxp 已提交
363

W
x  
wanganxp 已提交
364
**让跨平台开发不如原生,成为历史**
W
wanganxp 已提交
365

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
欢迎体验 hello uni-app x 示例应用,Android、iOS、Web 三个平台都有,可以亲身感受它的启动速度,渲染流畅度。

<div class="quick">
  <div style="margin-top: 20px;justify-content: space-around;">
    <a
      href="https://hellouniappx.dcloud.net.cn"
      target="_blank"
      style="display: flex; align-items: center;flex-direction: column;margin: 0 5px 20px;width:160px;"
      one-link-mark="yes"
    >
      <div class="barcode-img-box">
        <img
          src="https://web-ext-storage.dcloud.net.cn/uni-app-x/hello-uniappx-qrcode.png"
          width="160"
          loading="lazy"
        />
      </div>
      <b>hello uni-app x</b>
    </a>
  </div>
</div>

源码在:[https://gitcode.net/dcloud/hello-uni-app-x/](https://gitcode.net/dcloud/hello-uni-app-x/)
W
x  
wanganxp 已提交
389

W
wanganxp 已提交
390 391
这个示例里有几个例子非常考验通信性能,除了也内置了slider-100外,另一个是“模版-scroll-view自定义滚动吸顶”,在滚动时实时修改元素top值始终为一个固定值,一点都不抖动。

W
x  
wanganxp 已提交
392
我们不说服您使用任何开发技术,但您应该知道它们的原理和差别。
W
wanganxp 已提交
393

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
394
欢迎指正和讨论。