flutter
flutter是 Google 为 Fuchsia 操作系统设计的应用开发方式。
Fuchsia OS要兼容廉价物联网设备,要求对硬件的消耗降低,并且为了避免与oracle的java打官司,Fuchsia 使用了dart语言+flutter界面库的方式。
对比分析
性能分析 和 写法对比
flutter作为界面库,它唯一要干的事情就是渲染界面。不像HTML5,flutter界面库连视频、定位等都没有,就是一个纯排版引擎,绘制文字、按钮、图片等常用界面控件。
这个排版引擎的特点是简单、高性能。
提升性能是有代价的,开发便利性和运行性能不可兼得。
举个例子,同样的界面,用HTML和flutter如何实现:
smaple text
.greybox {
display: flex;
align-items: center;
justify-content: center;
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 18px
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff
}
var container = new Container( // grey box
child: new Center(
child: new Container( // red box
child: new Text(
"smaple text",
style: new TextStyle(
color: Colors.white,
fontSize: 18.0,
),
),
decoration: new BoxDecoration(
color: Colors.red[400],
),
padding: new EdgeInsets.all(16.0),
),
),
width: 320.0,
height: 240.0,
color: Colors.grey[300],
);
可以看出,从代码的写法来说,flutter没有tag和样式的说法,更没有选择器,从头到尾只有dart语言,它的界面控件是用dart代码new出来的,每个控件的样式,是在new的时候设置的类json写法的参数。
flutter的性能高,除了简单严格,还有一个特点,就是逻辑层与视图层统一,运行在同一套dart虚拟机下。
我们知道rn和weex,也是原生渲染的,它们的性能高于webview。但同为原生渲染的,怎么会慢于flutter呢?其实不是原生渲染慢,而是js和原生通信慢。
rn和weex都采用了独立的js引擎(iOS是jscore,Android是v8,最新版rn开始在Android上搞自己的js引擎Hermes),从js与dart的比较上,性能稍逊一筹。但这不是主要问题,因为v8的jit不是盖的,也是编译为原生代码解析的。性能上的主要问题是:rn、weex的js引擎和原生渲染层是两个运行环境。
当js引擎联网获取到数据后,通知原生视图层更新界面时,有一个跨环境的通信折损。同样,当用户在屏幕上操作原生视图层时,要给js引擎发送通知,也会产生这个通信折损。
不过这种性能差别,在大多数场景中,用户是感受不到的。比较影响的场景,是跟手式的js响应操作绘制帧动画,或者说js连续操作界面元素方面,flutter折损更少。
这个通信折损,其实普遍存在于所有逻辑和视图分离的框架中,包括各家小程序也有这个问题。
说回来flutter,它只有一个dart引擎,没有来回通信产生的性能问题。不过任何事情都是有利有弊的,flutter在普通的界面绘制上效率虽然高,但一旦涉及原生的界面,反而会遇到更多问题。
前面已经说过,flutter只是一个基础排版引擎,缺少很多能力,当我们需要在flutter界面上内嵌一个原生的视频播放扩展控件时(flutter没有内置视频播放能力),或者原生的高德地图sdk,那么在拖动视频进度时、拖动地图时,flutter一样会产生原生和dart之间的通信,造成性能损耗。
事实上,由于flutter是在一个类canvas环境绘制的,想把一个原生控件嵌入flutter的布局里某些元素之间去排版,还不是一件容易做到的事情,坑很多。
性能好,有个度,客观地讲,rn/weex调用原生渲染的性能,和flutter的渲染性能,在用户体验上并没有明显区别,甚至在很多场景下,和webview渲染的小程序也没有明显区别。
也简单说说webview渲染小程序,为什么性能高,核心是预载。点击一个新页面时,webview是提前创建好的,不会走复杂的webkit、v8的初始化流程,连开发者的js代码,也是预载好的。所以点击新页面时,它的渲染速度和原生应用没什么差别。当然也有个坏处,就是启动慢。微信里启动小程序速度看着还行,其实是微信在启动小程序之前,就已经提前初始化了小程序运行环境。
ui 库
不管是rn还是flutter,有一个设计,很不中国化。它们在iOS和Android平台上,使用2套ui库。
rn和flutter这种“跨平台”排版引擎,其跨平台性,对于中国开发者而言,又打了折扣。
其实类似小程序那样的ui风格,是能够良好的跨iOS和Android的体验的,不管用什么手机,打开小程序都不会觉得有问题。
uni-app默认也是这种通用ui风格。uni-app的开发者只需要写一套界面ui,就可以适应不同手机的用户,真正的 write once,run anywhere。
动态性
webview、rn/weex,都有一个特点,可以远程动态载入js代码,可以更新本地的js代码。前端开发者认为动态性是天经地义的,但其实flutter并不支持。
flutter是有编译优化概念的,如果它提供动态性支持,会影响它的性能。
除了flutter,rn/weex/uni-app都可以动态热更新。
跨平台排版引擎 和 跨平台应用开发引擎 的区别
一个页面跨平台,和一个应用跨平台,是完全不同的2个概念。
webview、rn/weex、flutter全部是渲染引擎,webview因为HTML5的发展,还算是多了一些能力比如位置服务、多媒体等。而rn/weex、flutter真的只是一个纯粹的排版引擎,没有任何原生能力。
什么是跨平台应用开发引擎?不但排版部分要跨平台,开发API也要跨平台。
应用开发离不开os或三方sdk的能力调用,如果是单纯的排版引擎,一旦涉及os能力和sdk调用,就必须iOS、Android的工程师配合,编写不同的原生代码整合在一起。这就不跨平台了。
uni-app,它的设计目标不是跨平台排版引擎,而是跨平台应用开发引擎。
所以uni-app的排版部分,可以选择小程序强化webview引擎和weex引擎,可根据自己的需求切换。而能力层面,uni-app提供了htmlplus API、Native.js、插件市场,解决了原生能力js化的问题。
uni-app让开发者真的不用懂原生开发就能做出完整的跨平台应用。遇到极个别的需求,开发者也可以去插件市场找人订做一个原生插件,自己仍然使用js来集成,仍然可以云端直接打包。
学习成本、难度
rn,要求开发者学习react,要求精通flex布局,要求原生开发协作。
flutter,要求开发者学习dart,了解dart和flutter的API、要求精通flex布局,要求原生开发协作。
weex已经内嵌到uni-app中,就不单独提了。
uni-app,要求开发者学习vue,了解小程序。
生态
任何开发引擎,都离不开生态。
对于国外的开发者,rn、flutter的生态肯定比uni-app好,比如facebook登陆分享、Google地图等。
但对于国内的开发者,那是反过来的,中国开发者需要的全端推送(UniPush集成了iOS、华为、小米、OPPO等众多原厂推送)、各种国内登陆、支付、分享SDK、各种国内地图、各种ui库、以及Echart图表等,都是在uni-app体系里,这方面生态可比rn、flutter丰富多了。uni-app的插件市场有数千款插件,不能说应有尽有,但确实是最丰富的跨端开发框架生态了。
另外,uni-app的生态还比其他竞品强在如下方面:
- App和H5提供了renderjs技术,使得浏览器专用的库也可以在App和H5里使用,比如echart、threejs等
- 兼容微信小程序 JS SDK,丰富的小程序生态内容可直接引入uni-app,并且在App侧通用
- 兼容微信小程序自定义组件,并且App、H5侧通用
总结
flutter与uni-app的比较:
flutter与uni-app的相对优势:
- 性能好一丢丢。比rn有优势,但比拥有bindingx和wxs的weex/uni-app,在实际开发中没有很明显的差距。
flutter与uni-app的相对劣势:
- 需要原生协作,维护3套代码,无法有效降低开发成本,提升开发效率
- 嵌套地狱,代码难看难维护
- 不支持热更新
- 目前质量和成熟度很低
- 原生可视控件融合不好,比如webview、video、map
- ui库不适合国情
- 学习成本高
- 应用场景有限,dart未来扑朔迷离
uni-app里其实也可以使用flutter,有插件作者提供了插件,使得uni-app的应用在某些页面可以打开flutter页面
rn 和 uni-app的比较
rn与uni-app的相对优势:
- rn的坑虽然比weex的少,但uni-app已经填了weex的很多坑。这方面差别不大。
- rn的生态虽然比weex丰富。但uni-app是反过来的,uni-app的国内应用生态丰富度超过了rn。
- rn是纯单页的,嵌入原生App比较灵活。而uni-app是应用整体的概念,如果要内嵌入其他原生应用的话,要求原生应用内嵌uni-app应用整体进来。即集成uni小程序sdk。
rn与uni-app的相对劣势:
- 需要原生协作,维护3套代码,无法有效降低开发成本,提升开发效率
- 不支持小程序,发布到h5也无法直接发
- 性能不如uni-app
- 国内的插件生态不如uni-app丰富
- ui库不适合国情,learn once,write anywhere
- 学习成本高,用人成本高,不利于开发商降低开发成本
- rn是纯单页应用,如果一个应用的页面很多,用rn写会很崩溃,变量污染和干扰严重。而weex/uni-app支持多页面,页面之间上下文隔离,写页面较多的大型应用更合适
- 另外react在中国的市场占有率远不如vue。这也是中国与国外不同的特色情况。