跨平台和大前端那些事
1、为什么需要跨平台和大前端
2、跨平台和大前端目前的现状,解决方案
3、unity怎么实现跨平台
4、unity与原生的关系
5、有哪些需要原生代码实现 (遇到的问题)
6、总结
1、为什么需要跨平台和大前端
大前端是什么呢,直接来说,大前端是所有前端的总称,最接近用户的那一层都叫前端,比如 Android、iOS、Web、Watch、小程序等。
在企业的开发中会遇到这样一个头疼的问题。当企业需要上线一个新产品时,服务端只需要开发一次,但是面向用户的客户端也就是前端却需要开发多个版本,比如 Android 版、iOS 版、H5 版、小程序版等。每一个版本的开发工作量都是无法复用的,这意味企业需要付出更多冗余的人力成本。这个时候问题就来了:有没有一种技术可以同时适用于多个平台呢?这种技术就是跨平台技术。有了跨平台技术,各个平台的差异性就被抹平了,开发者只需要一套技术栈就可以开发出适用于多个平台的客户端,这就是大前端生态中最重要的一环。
所以说:随着 CPU 等各种硬件性能的提升,语言之间带来的一些性能差,慢,都会被硬件提升所抵消,甚至在以后让你都感觉不到了,即使语言性能很差,但是硬件的提升,还会让你感觉有些硬件性能过剩。语言是干不过硬件的。
2、跨平台和大前端目前的现状,解决方案
截止目前,主流的跨平台方案有:
(1)ReactNative(FaceBook)、
(2)Weex
(3)flutter
(4) unity
1、 React-Naitve(FaceBook开源出来的框架)
前端框架React,2013年发布,基于JavaScript的,可以用简洁的语法高效绘制DOM。
React-Native 是FaceBook在2015年开源的,一个基于 JavaScript,面向前端开发者的移动端开发框架。
React-Native和 React的编程思路有些不同,React是以WebView(浏览器)为后端,操作Virtual DOM进行视图渲染的,而React-Native是以ios或者anroid原生控件为后端,但以React component 的方式Expose出来进行视图渲染的。
RN使用Javascript语言来开发移动应用,但UI渲染、网络请求等均由原生端实现。具体来说,开发者编写的Javascript代码,通过中间层转化为原生控件后再执行,因此熟悉Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域,并可以在不牺牲用户体验的前提下提高开发效率。
作为一个跨平台技术框架,RN从上到下可以分为Javascript层、C++层和Native层。其中,C++层主要用于实现动态连结库(.so),作为中间适配层桥接,实现js端与原生端的双向通信交互。
优点:
(1)调试方便
(2)css—layout布局
(3)跨平台
(4)热更新
(5)Facebook背书
缺点
(1)学习成本高
(2)脚本语言 开发体验一般。
(3)不同平台有时候表现差异很大
(4)控件不完善
(5)要做出优质app需要花费大量人力和时间去打磨 最后很多公司发现并没有减少开发成本。
React Native开发的App75%的代码是一样的IOS和Android, 25%的代码是针对不同的平台写。
热更新:
ios:屏蔽了部分热更新框架,有些还是能够用的。
android:对于通过 Google Play 分发的应用,不得采用 Google Play 更新机制以外的其他任何方式修改、替换或更新应用本身。同样地,应用不得从 Google Play 以外的其他来源下载可执行代码(例如 dex、JAR 和 .so 文件)。
百度内部要求全面下架 React 和React-Naitve。由于Facebook 新的条例
如果你使用了 React,你不能做构成与 Facebook (包括其子公司及其合作方)竞争的事情,一旦你做了,就会有极大的潜在危险。
2、weex
由阿里巴巴开源的跨平台移动开发工具。支持iOS、安卓、YunOS、移动Web 、PC WEB。
关键词:跨平台、高性能、Vue、W3C标准、三端一致。
开发框架是 VUE ,学习曲线比较平缓。资料不足,文档简单,第三方支持较弱。主要是的实现思路是webview的封装,可以理解为增强型的web,所以性能不是太好。性能不及RN。
作为一套前端跨平台技术框架,Weex建立了一套源码转换以及Native与Js通信的机制。Weex表面上是一个客户端框架,但实际上它串联起了从本地开发、云端部署到分发的整个链路。 具体来说,在开发阶段编写一个.we文件,然后使用Weex提供的weex-toolkit转换工具将.we文件转换为JS bundle,并将生成的JS bundle上传部署到云端,最后通过网络请求或预下发的方式加载至用户的移动应用客户端。当集成了Weex SDK的客户端接收到JS bundle文件后,调用本地的JavaScript引擎执行环境执行相应的JS bundle,并将执行过程中产生的各种命令发送到native端进行界面渲染、数据存储、网络通信以及用户交互响应。
当JS bundle从服务器下载完成之后,Weex的Android、iOS和H5会运行一个JavaScript引擎来执行JS bundle,同时向各终端的渲染层发送渲染指令,并调度客户端的渲染引擎实现视图渲染、事件绑定和处理用户交互等操作。 由于Android、iOS和H5等终端最终使用的是native渲染引擎,也就是说使用同一套代码在不同终端上展示的样式是相同的,并且Weex使用native引擎渲染的是native组件,所以在性能上比传统的WebView方案要好很多。
当然,尽管Weex已经提供了开发者所需要的最常用的组件和模块,但面对丰富多样的移动应用研发需求,这些常用基础组件还是远远不能满足开发的需要,因此Weex提供了灵活自由的扩展能力,开发者可以根据自身的情况定制属于自己客户端的组件和模块,从而丰富Weex生态。
RN和weex 对比
Weex的目标是实现代码共用,一次开发多平台运行,能同时支持IOS、Android和Web,降低了开发难度,节约开发成本;
React Native则希望替换整个APP,所以更加注重平台的独立性,其代码需要针对IOS和Android平台编写,代码无法实现完全公用,从官方提供的组件也可以很明显的看出。
目前天猫, 淘宝,飞猪等些界面是使用了weex进行开发。
(3)Flutter
Flutter是Google开源的移动跨平台框架,该项目可以同时运行在Android、iOS和fuchsia(Goole用于替代android的操作系统)等包含Dart虚拟机的平台上,并且性能无限接近原生。相较于RN和Weex使用Javascript作为编程语言与使用平台自身引擎渲染界面不同,Flutter直接选择2D绘图引擎库skia来渲染界面。
苹果为了应对google 的Flutter 也推出了自己swiftui。
Swift UI是苹果系统的一个跨平台iOS、Mac OS、TV OS、iPad OS、Watch OS的UI框架。将成为苹果生态UI开发的基础。
对比类型 | React Native | Weex | Flutter |
支持平台 | Android/IOS | Android/IOS/Web | Android/IOS |
实现技术 | JavaScript | JavaScript | 原生编码/渲染 |
引擎 | JS V8 | JSCore | Flutter Engine |
编程语言 | React | Vue | Dart |
bundle包大小 | 单一、较大 | 较小、多页面 | 不需要 |
框架程度 | 较重 | 较轻 | 重 |
社区 | 活跃、FB维护 | 不活跃 | 活跃 |
性能测试结论
1、包体积原生比较小,Flutter和RN不相上下(Ios系统需要引入Skia库,最终包体积Flutter会明显大于RN),由于Flutter和RN框架中需要一些C++依赖库,导致包体积比原生大了很多。
2、启动时间,Flutter(冷热启动时间)>RN=原生
3、内存占用,在高端手机上,flutter占用内存是大于RN的,但是低端手机Flutter的内存占用会低于RN,RN内存占用不稳定,页面刚生成的时候内存占用会高一点, 之后缓慢回落。
3、CPU占用,RN明显高于Flutter和原生,这会导致手机性能降低、耗电量增加、发热更厉害
4、主观感受,Flutter要比RN更加流畅,体验感更好,但是和原生仍有不小差距,不过Flutter还很年轻,官方宣称其性能会接近原生,甚至超过原生体验,随着Google不断的改进相信在不远的将来会实现这个可能。
(4)Unity实现跨平台
3、unity怎么实现跨平台
Unity 3D 也称 Unity,是由 Unity Technologies 公司开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具。
unity 可以开发2D平面,3D立体,AR(增强现实),VR(虚拟现实)等
Unity 3D 游戏可发布的平台包括 Windows、Linux、MacOS X、iOS、Android、Xbox360、PS3 以及 Web 等。
特色:
(1)跨平台
跨平台开发可以为游戏开发者节省大量时间。
(2)综合编辑
可视化的编辑,详细的属性编辑器和游戏动态预览。当游戏运行时可以实时修改参数值,方便开发,为游戏开发节省大量时间。
(3)资源导入
使用unity3d的Asset bundle方法,打包后的安装包不包含资源,在第一次运行时会在网上下载资源,这样就能缩小打包后文件的大小
项目可以自动导入资源,并根据资源的改动自动更新,贴图材质自动转换为 U3D 格式,协同工作。
(4)脚本语言
Unity 3D 集成了 MonoDeveloper 编译平台,支持 C#、JavaScript 和 Boo 3 种脚本语言,其中 C# 是在游戏开发中最常用的脚本语言。
(5)联网
Unity 3D 支持从单机应用到大型多人联网游戏的开发。
(6)着色器 (shader)
Unity 3D 着色器系统整合了易用性、灵活性、高性能。
(7)地形编辑器
Unity 3D 内置强大的地形编辑系统,该系统可使游戏开发者实现游戏中复杂的地形,支持地形创建和树木与植被贴片,支持自动的地形 LOD、水面特效,尤其是低端硬件亦可流畅运行广阔茂盛的植被景观,能够方便地创建游戏场景中所用到的各种地形。
(8)物理特效
物理引擎是模拟牛顿力学模型的计算机程序,其中使用了质量、速度、摩擦力和空气阻力等变量。Unity 3D 内置 NVIDIA 的 PhysX 物理引擎,游戏开发者可以用高效、逼真、生动的方式复原和模拟真实世界中的物理效果,例如碰撞检测、弹簧效果、布料效果、重力效果等。
(9)光影
Unity 3D 提供了具有柔和阴影以及高度完善的烘焙效果的光影渲染系统。
Unity 跨平台原理
Unity引擎本身是由C++写出的,只不过Mono被嵌入到了Unity当中,为unity提供了一个完整的虚拟机运行环境。这样Mono的嵌入接口会将Mono Runtime暴露给Unity底层的C++代码。通过这些接口,开发者就可以控制Mono Runtime,以及依托于Mono Runtime的托管代码。
Unity的跨平台,就是通过Mono将C#脚本代码编译成CLI,然后Mono运行时利用JIT或者AOT将CLI编译成目标平台的原生代码实现的。
JIT:即时编译,或者又称为动态编译**,是在程序执行时才编译代码,即将一条中间托管语句(CLI)翻译成一条机器语句,然后执行这条语句。但它同时也会将编译过的代码进行缓存,而不是每一次都进行编译。
AOT:静态编译**,同样使用了JIT来进行编译,只不过它在程序运行之前就编译好了。但还是有一部分代码会即时编译。
AOT的过程简要:
1)收集需要编译的代码。
2)使用JIT编译代码。
3)发射编译过的代码和一些元数据
4)调用本地汇编器或连接器处理后生成可执行文件。
注:IOS平台禁止使用JIT编译器,所以Mono提供了一种FULL AOT模式。
4、unity与原生的关系
unity是通过静态编译,生成ios 或者 andoird 的包。
unity更像是一个画布,主要的需要展现的界面,包括动画,人机交互的东西展现给用户。同时unity实现了与ios或者andorid 交互的接口。能够让我们实现ios或者android跟unity 进行交互。平台相关的需要android和ios分别实现。
(1)关于图形
Unity支持的图形API有OpenGL、OpenGL ES、WebGL、Metal以及DirectX,每个API都对应不同的平台。
OpenGL应用很广泛,一些iOS设备、Mac OS X和Linux,甚至Windows都用到了OpenGL。
OpenGL ES兼容手机设置,支持大多数和部分iOS设备。
WebGL是一个新平台,基于浏览器图形运行应用和游戏,无需再安装Flash或Unity WebPlayer这样的插件。
Metal是苹果新出的图形API,兼容大多数近期的iOS设备及Californian公司的电脑。
DirectX是微软自制的图形API解决方案,兼容Windows、Windows Phone以及Xbox。
(2)关于网络
unity自己实现,在2014年发布了其自制的网络和多玩家解决方案UNET。
(3)关于脚本
用于跟原生平台通信和mono运行环境进行通信
5、有哪些需要原生代码实现
(1)平台相关的需要原生代码实现
比方说 获取本机的手机唯一标示,震动,打电话,发email等
(2)平台相关性较强的
iOS平台上我们要从一个应用唤起另一个应用
在我们的游戏中打开一个网页,或者是直接嵌入一个iOS原生的界面
(3)对接第三方sdk
当对接的第三方sdk 之后android 和ios 版本没有unity 版本时候,我们还想要接入的时候
比方说微信登录、微信支付、第三方分享
第三方广告平台不支持untiy平台,只支持ios和android 平台时候
(4)unity实现效果不好的时候
比方说一个第三方平台支持ios android 和unity 三个版本。
但是unity 有明显的bug,但是对于ios或者android 很稳定。我们可以使用unity和跟原生通信的方式来实现相对应的功能。
目前遇到的是对于ios 内购相关,unity内购有明显的回调问题,调试困难比较大,但是ios 内购是比较稳定的,所以用ios 实现,实现结果返回给unity
(5)开发的App75%的代码是一样的, 25%的代码是针对不同的平台写。
6、总结
所以对于跨平台我们有三种大的方案:
(1)翻译成原生的实现方式,不同的平台调用不同的方法,但是ui统一性比较难控制,对于开发者要求较高,需要懂每个平台的特性,主要代表是RN。
(2)基于web实现方式,自己提供比较高效的实现方法,效率会受影响,主要代表是weex。
(3)提供一个新的引擎和渲染机制,主要就是提供一个画布来实现ui,原生特性比较高的用原生去实现。这一类代表是Flutter 和unity。
对于那些需要原生来实现的
(1)凡是平台相关性都必须原生实现
(2)原生相关性强的最好用原生实现
(3)第三方不支持的用原生实现
(4)第三方支持不好的,可以用原生替代当前解决方案。
(5)开发的App75%的代码是一样的, 25%的代码是针对不同的平台写。