跨平台开发方案:uniapp、flutter、react-native浅析

  前言

  最近在做uniapp的项目,也遇到了各种各样的渲染的问题,很多小伙伴会一头雾水,为什么渲染会这么卡顿慢?为什么明明数据量一致却远没有原生来得痛快流畅?当然有算法本身或者实现业务的问题,也有方案框架本身的问题,这里将会就跨平台方案维度进行解析。

  Uniapp、RN、Flutter区别以及背景

  uniapp背景

  先说语言技术栈,uniapp是vue技术栈,一开始只有vue2,虽然后面支持vue3了,但是貌似框架底层的支持缺陷还是很多的,比如有些我们默认的一些vue全家桶库的支持并不好(vueX等)。

  其实对于玩过微信小程序和京东Taro的人会发现,uniapp的官方文档风格其实和小程序是没有差异的,甚至于说连文件目录结构都和小程序没有差异,但底层API和组件的提供上却是小程序的子集关系(小程序支持的,uniappp不支持),而且如果你的需求只是开发小程序,vue语法和小程序语法几乎没有决定性区别的情况下是还不如用原生小程序开发,支持的API更多,书写反而更加简单。

  当然再说背景,uniapp和Hbuilder有十分十分十分十分十分十分强烈(这个一定要强调)的工程绑定关系,uniapp官方几乎对于技术的依赖真的只能靠团队零散几个大神支撑,感觉大量的成本和时间在推广运营这一侧(比如各个群里貌似水军的狂热分子),uniapp的开发很多功能打包调试的过程都只能依赖Hbuilder,有点为了推广Hbuilder而忽略技术沉淀本身的感觉,当然这几年也针对uniapp进行了升级,通过一系列配置,多少也能支持cli命令打包和使用vscode进行开发了。

  uniapp的优点

  跨平台开发是为了解决js工程师打破原生安卓或者IOS开发者之间的开发壁垒,所以一般情况下,如果是为了快速低成本的招前端员工来进行没有复杂交互场景和大数据渲染的情况,uniapp绝对是当前跨平台方案中最快的。

  另一方面就是如果你有一个项目需要同时进行小程序和移动app的迭代需求,公司人员少,uniapp也是个好选择,但问题在于对于复杂节点渲染的场景,其实技术支持力度还不如京东的Taro,技术团队也没有京东来的迅速(例如fragment渲染),即便当前已经支持了Vue3,但是由于市面uniappUI库以及官方插件都是针对vue2的开发,一旦项目升级到3,但是却不能向下兼容那些三方库了,而且3的语法层级也多很多多余封装。

  然后对于一些less、scss之类的样式写法倒是非常舒服支持力度也可以。最主要的是uniapp是双引擎渲染,同时支持webView和weex渲染。

  uniapp的缺点

  其实在讲优点的时候顺带提到了缺点,这也是没办法的,因为为了让开发人员傻瓜化而让开发的上限降低也是没有办法的,双引擎的开发表面上是学习成本降低了,但是渲染效率也会随之下降很多很多倍,当下市场上并没有uniapp比较具有代表性的或者具有现象级别的产品,大部分都是中小企业的快速产物,换句话就是uniapp并不适合做产品,如果想要保证成果物的细粒度化操作和优化,uniapp就会是一个噩梦。

  而且最要命的是uniapp的js和原生的通信问题,当前这个框架采用vue,采用云打包的方式生成apk发布使用,这个框架我并不看好,开发者可以打开布局边界查看下布局,其中完全使用网页的形式呈现给用户,基本跟android不怎么挂钩,即便挂钩,官方也已经作出了api供用户使用。虽然说完全使用网页的形式制作,但性能方面……哈哈,因为官方做出了很多网页的优化,具体性能劣势于flutter,reactNative。

  react-native背景

  语法是react,而且目前也支持函数组件开发了(hooks),说实话不论是语法简洁性和学习成本同过去的RN真的是质的飞跃,但js和native的通信机制开销依然很大……

  团队背景是facebook团队,技术的支持专业度相比uniapp还是比较高的,和google的flutter也是旗鼓相当,并没有额外的IDE的营销成本,对于不同的IDE爱好者都很友好。

  其实和uniapp比较像,因为尤雨溪的原因,所以uniapp用vue,因为facebook的原因,所以是react。只是这个团队比起营销还是会更注重技术(国内外行情毕竟不一样,要活下来吧)

  react-native的优点

  复杂场景的渲染颗粒度要高一点,自由度更高,同比渲染效率会比uniapp高(我想这就是react和vue框架上的差异导致的吧),相比较而言不会限制IDE,纯开发角度而言,在工程角度上RN可以做到的事情更多,很多复杂业务场景的实现上可以更加灵活。

  打包效率没得说,毕竟人家可以细粒度化操作,虽然uniapp也能强行做,但相对心力损耗就大得多了。

  然后市场上也有很多成熟的产品:

  react-native的缺点

  之前也说到过,uniapp支持小程序、app、H5,人家老外没有小程序这玩意儿,所以根本不打算去做这种事,就跨平台多端内容性肯定是没有uniapp多的,目前人家还是专注于web、安卓、ios方面的支持,另一点是样式书写的问题,虽然你可以强行在工程上采用scss、less的写法,但有一些写法是不支持的(例如sticky等),只能切换实现思路,样式的书写属于写了一个style对象,然后内联进去(就跟安卓原生的本质没有区别),但也正因为这种约束,部分样式的效率还是比uniapp高的。

  但是也因为不约束你的IDE,所以前期的工程准备成本相对会高一些,再加上中国有一堵伟大的墙,安装某些工程内容的时候还是很心累的(一般出现在ios开发中)。

  通信侧也会出现 JS 到 Native 之间通信开销,导致交互的流畅性受损,当然uniapp也一样。这也是为什么不论是RN,还是uniapp,大家都会吐槽交互流畅性的本质问题。

  flutter的背景

  语言是Dart语法,很多前端小伙伴一下子就懵逼了,背景是Google,世界顶尖科技巨头,至于为什么选择Dart的原因,人家技术官很不好意思地解释了一下:“因为当时Dart就在我们旁边,所以能够得到对应的技术反馈……”,好家伙,有的东西真的不是说为了考虑所有的方便才去开发,而是当时的资源,才有了现在的技术选择……

  flutter的优点

  中国市场上的hybrid混合开发基本上都会涉及到一个概念,就是JSBridge。

  无论是uniapp、还是rn,工程开发的时候虽然是js,但最终还是会打包成一个原生包,也就是native,程序会通过jsbridge搭建起一个js与native之间的桥梁,js做什么操作,返回反馈给native对应的命令,当然这也解释为什么明明在浏览器端有些js语法支持,到了RN和uniapp中就不行的原因,因为不存在对应的native和js的命令映射关系呀!所以有的公司会专门请一个工程师去解决native和jsbridge的问题(例如阿里的1688就是基于weex的hybird开发)。

  然后像是RN和uniapp(其实我感觉uniapp的UI是优先适配小程序组件库的……),为了能够让UI有效渲染,还是拿的原生最简单的一些View组件进行封装,然后像是一些比较复杂的UI组件还是需要工程师自己一层套一层实现,自然而然这个渲染压力就会上来,毕竟不是原生,再加上通信开销,卡就会变的很正常,所以一些大厂也会专门找人做这种底层组件保证效率。

  这里就完全体现了flutter的伟大之处,这里引用别人的几句话Flutter 是 Google 开源的 UI 工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台,Flutter是完全免费、开源的。它也是构建未来的 Google Fuchsia 应用的主要方式。flutter根据google推出的flutter SDK进行编写,完全颠覆了android的开发理念,须知道,android flutter都是google的, android开发使用的android SDK,flutter却不然,自制了一套自己的SDK,直接使用GPU渲染机制,在用户手机上 非常直接的 canvas draw view,其手段非常牛逼。reactNative 的bridge(桥接)技术也是很厉害的!他通过了android 与 js之间构成了bridge,中间经过了编译,最终进行了android控件转换,这点有些像javac编译class那一块了,最终绘制在用户手机上的是原生控件。其中性能问题并不算太大,因为得到的是原生页面,所以比较受欢迎。相对比下来 rn中间那层转换编译 对于 flutter来说是没有的,相对来说flutter是最直接的,但这里我也要指出,对于目前用户手机性能来说,现在android已经到11了,中间那部分转换损耗的性能,用户基本是感知不到的。

  而且也存在成熟产品:

  如此一来,flutter的优势也真的很强了!

  flutter的缺点

  一句话,语法!成也语法败语法,先不说当下Dart语言的开发群体有多少,招工好不好招,有那时间学习flutter,我还不如直接学习android,而且复杂交互里一层套一层的写法真当是把人恶心坏了,这边举个例子:

  HTML写法

  Flutter写法

  看官明白了吧?这么开发工程,这学习成本和开发当真是还不如原生开发吧?

  而且不支持热更新真的难受,就算使用了三方也会造成性能损耗……

  -----------------

  这里修改一下,flutter支持热更新啦!!感觉热更新还不错!(记录于2022年9月27日)

  三者总对比

  移动端生态而言

  原生 > RN > Uniapp >Flutter

  学习成本

  原生 > Flutter > RN > Uniapp(但其实随着hooks的入场,RN的学习成本和Uniapp差距不大了)

  渲染效率

  原生 > Flutter > RN > Uniapp