跨平台技术优势
原生开发不足:
- Android、iOS分开维护,开发和测试成本大。对于小团队来说成本较大。
- 动态化弱,更新需发版。
跨平台优势:
- 增加代码复用,减少开发者对多个平台差异适配的工作量,降低开发成本。
- 多端UI和交互一致。
- 动态化,热更新。
- 热重载。
跨平台不足:
- 接入成本
- 不可避免要和原生通信
- 性能弱于原生
跨端技术演进
WebView(Web App) | Hybrid(WebView+) | JS+原生渲染 | 自绘UI | |
---|---|---|---|---|
介绍 | 使用原生Web容器,JS引擎解析,WebKit或者Blink渲染 | 混合开发,WebView增强。通过JSBridge进行原生通信和调用 | 类RN方案,生成虚拟Dom,JSCore映射成原生控件渲染。 | Dart编译,Flutter提供渲染引擎自绘 |
代表框架 | H5、PWA | Cordova、Ionic、小程序、PhoneGap | RN、Weex、Hippy、快应用 | Flutter、QT |
虚拟机(运行时) | JS引擎(V8、JSC) | JS引擎+JSBridge | JS引擎 | Dart VM |
渲染引擎 | WebKit、Blink | WebKit、Blink | Native渲染 | 2D:Skia(SGL) 3D:OpenGL ES |
性能 | 差 | 差 | 原生渲染,运行时解析Dom树,和原生通信 | 接近原生 |
Hybrid原理:
原生渲染原理:
自绘渲染原理:
- PWA(Progressive Web App,渐进式Web App):离线缓存、无需安装、服务端首屏渲染。
- Weex:阿里巴巴出品,使用vue框架开发
- 快应用:国内手机厂商出品,使用JS开发,将引擎内置到ROM中,减少应用体积。
- Taro:可以使用TSX、JSX、React语法,编译成不同平台的代码(RN、微信/支付宝/京东小程序、快应用、H5等)
js调用Android方式:
WebView.addJavaScriptInterface()
WebViewClient.shouldOverrideUrlLoading()
Android调用JS方式:
WebView.loadUrl()
WebView.evaluateJavaScript()
RN和Flutter对比
类型 | React Native | Flutter |
---|---|---|
原理 | JSCore引擎解析React虚拟Dom,渲染成原生控件树。 | skia引擎自绘UI |
技术栈 | React | Dart |
开发者 | ||
支持版本 | Android 4.1(API level 16)以上 | Android 4.1(API level 16)以上 |
支持平台 | Android、iOS | Android、iOS、Web、桌面、Fuchsia |
包体积 | iOS系统自带JS Core,Android系统不带 | Android系统内置Skia引擎,iOS系统不带 |
UI一致性 | 低:不同平台控件单独维护,复杂场景需要对原生控件进行扩展 | 高:一套代码,UI一致 |
原生调用 | JS Bridge | Platform Channel |
动态化 | 支持 | 不支持 |
热重载 | 支持 | 支持 |
性能对比
只对比Android和RN、Flutter
启动速度、内存、CPU多次测试取平均值。通过脚本模拟滚动列表操作。
Android | Flutter | RN | |
---|---|---|---|
运行效率 | 1.0:Dalvik+解释器。 2.2:Dalvik+JIT。 5.0:ART+AOT。 7.0:混合编译。 9.0:编译模版 |
Debug是JIT,Release是AOT。 | Js运行时编译,渲染需要和原生通信。 |
Release包 | 3.5M | 未分包16M,分包5~6M | 未分包30.1M,分包后10M左右 |
冷启动 | 329ms | 395ms | 341ms |
温启动 | 242ms | 288ms | 243ms |
热启动 | 89ms | 57ms | 53ms |
内存占用 | 61.768M | 75.747M | 105.117M |
CPU占用 | 52.040% | 63.660% | 67.820% |
FPS(帧/s) | 93.989 | 23.584、80.645 | 96.647 |
View数量 | 57 | 9 | 93 |
Display list | 80.98KB | 12.53KB | 138KB |
GPU | 4.37MB | 48KB | 4.2MB |
进程总耗电量 | 0.306mAh | 0.332mAh | 0.520mAh |
进程CPU耗电量 | 0.0000800mAh | 0.000383mAh | 0.00154mAh |
过度绘制 |
温启动:进程没被杀,Activity被回收,例如双击返回退出,或者app内存不足被回收
Flutter打包:flutter build apk --split-per-abi
RN打包:./gradlew assembleRelease
1 | // app/build.gradle |
总结
性能:
- 渲染性能:原生=Flutter>RN>H5
- 运行效率:原生>Flutter>RN
- 启动速度:原生>RN>Flutter
- 包体积:RN>Flutter>原生
- 耗电量:RN>Flutter>原生
- 过度绘制:RN>原生>Flutter
使用成本:
- 学习曲线、成熟度、普及度、社区生态、三方库、行业趋势:容易过时,不对比了。目前主流应该是Flutter。
- 框架程度:Flutter>RN>H5
- 接入成本:全新项目成本较低,原有项目接入成本较高
- 维护成本:原生需要维护两套代码。RN需要封装原生控件、Flutter需要封装插件
开发效率:
- 热重载:RN、Flutter支持热重载
- 工具链(开发、编译、调试、测试、发布):都挺完善的
平台一致性:Flutter>RN=原生
结语
Android性能分析请参考前面几篇Android性能分析大全
Flutter性能分析参考官方文档
Android性能分析脚本见GitHub-PerformanceCheck
Android、Flutter、RN测试Demo见GitHub-HybridPerformance