跨平台App对比
随着新技术得发展和PC向移动端过渡的强烈需求,前几年可以说是移动发展最火最快的几年。也催生了一大批 Android 和 iOS 的开发人员,但是在这个过程中公司的一个产品经常需要维护三个平台比如:iOS、Android、Web。而且平台之间语言不同,技术壁垒难以跨越,即使大佬精通多门语言,也需要铁打的身体支持。而且多平台对应的就是较高的开发和维护成本,尤其是对中小创业型公司来说更是堪称致命。所以跨平台开发呼声一直很高,对应的技术也有不少。比如 Cordova、Flutter、ReactNative、Weex、LuaView等等。今天主要抽几种对比一下。
一 跨平台 webApp
1.简介
这类 App 比较多,主要是Native 参与的比重不同,也有称之为hybrid
App。常用的Cordova、PhoneGap、APPCan、Ionic等 。
通用模式: Webview加载HTML. 通过JavaScript 和原生交互.
学识所限,仅介绍一下目前在用的 Cordova框架
举例: iOS 加载方式 UIWebview 和 WKWebView
Cordova中文网的地址是:cordova.axuer.com
Cordova中文社区:http://www.axuer.com/forum-84-1.html
官方介绍:“Apache Cordova是一个开源移动开发框架,它允许您使用标准的Web技术,如HTML5,css3和JavaScript进行跨平台开发,避免每个移动平台本机开发语言。应用程序在针对每个平台的包装内执行,并依靠符合标准的API绑定来访问每个设备的传感器,数据和网络状态。"
2.Cordova架构
cordova 架构示意图

简化版示意图

3.Cordova的优势
-
跨平台
Cordova为构建混合移动应用程序提供了一个平台,因此我们可以开发一个应用程序,将在不同的移动平台ios,android,Windows Phone,Amazon-fireos,黑莓,Firefox OS,Ubuntu和tizien上使用。
-
省时间
开发混合应用程序然后原生应用程序更快,所以Cordova可以节省大量的开发时间
-
易上手
由于我们在使用Cordova时使用JavaScript,我们不需要学习平台特定的编程语言。
-
社区
有大量的社区插件可以与Cordova一起使用。许多库和框架都经过优化以便使用它。
4.Cordova限制
- 混合应用程序比本地应用程序慢,因此对于需要大量数据和功能的大型应用程序使用Cordova不是最佳选择。
- 跨浏览器兼容性可能会产生很多问题。大多数时候,我们为不同的平台构建应用程序,所以测试和优化可能需要很多时间,因为我们需要覆盖大量的设备和操作系统。比如 iOS9 WKWebView ES5、6 语法兼容问题。
- 某些插件与不同的设备和平台存在兼容性问题。还有一些Cordova尚不支持的本机API。需要自定义插件,要找原生支援
- 举例:动画问题
上图是在餐饮 App 引入百度语音时,用户语言输入页面友好提示。(类似 Siri 监听语音输入时动态波浪)。结果机子发烫,GPU疯了的再跑。
- 另外转场动画,手势冲突等问题。
二.前端构建,原生渲染
1.React Native简介
React Native 号称是真正的移动应用?
React Native产出的并不是“网页应用”, 或者说“HTML5应用”,又或者“混合应用”。 最终产品是一个真正的移动应用,从使用感受上和用Objective-C或Java编写的应用相比几乎是无法区分的。 React Native所使用的基础UI组件和原生应用完全一致。 你要做的就是把这些基础组件使用JavaScript和React的方式组合起来。
ReactNative 中文网
2.Rreact Native App视图结构
RN布局代码
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
android:
'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text style={styles.instructions}>To get started, edit App.js</Text>
<Text style={styles.instructions}>{instructions}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
下图是 RN 测试 demo 视图结构。可见确实如介绍所说 RN 生成的是真正的移动应用。
最终调用的是原生的 UI 控件,原生图层结构

Ps:使用 RN 了解一下 JSX语法
3.React Native的优点
-
性能媲美原生应用
由于 React Native 提供的组件是对原生 API 的暴露。虽然我们是用 js 写的代码,但实际上调用的是原生 API,原生的 UI 组件。体验上足以媲美原生应用。
-
开发效率高
相比于原生开发,js 学习成本低、语法灵活。允许让 Web 开发者更多地基于现有经验开发 App。
-
组件化开发
React 强调将应用划分成多个互不相关的组件,每个组件作为一个独立的视图。这种类似搭积木的开发方式使得代码结构清晰、通用性高、可移植性高。上一个项目的某些组件,可以很方便地拿来在下一个项目中使用。对于那些优秀的第三方组件,也能很方便地集成到我们项目中来。
-
节约开发成本
百分之90多界面可以通过 React Native 开发,一份代码同时可以适配 Android 和 iOS。并通过一些手段自动匹配不同屏幕大小的手机,再也不需要自己去计算视图的大小和位置。
-
实时远程调试
React Native 的调试比 Cordova 不知道好到哪里去了。开启了实时重载之后,代码一改,app 就自动更新成最新,对于 UI 的搭建简直是省了不少的编译时间。同时可以打开 XCode 实时的看到所有的 log 信息。
-
代码热部署
我们知道 AppStore 审核流程超级久。而由于 React Native 是用的 js 来写的代码,实时编译的过程能让我们实现应用像网页一样做到热更新,随时发布。真正能够做到上架审核一次,永久 0 审核更新。
-
有效降低移动应用安装包体积
对于普通复杂度的移动应用,使用 React Native 实现的安装包会比原生代码实现的安装包大。而当移动应用功能越复杂,React Native 安装包体积相比原生代码安装包就越小。比如当原生代码实现的安装包大于 15MB 时,使用 React Native 改写代码后,安装包就小于原生代码实现的安装包。
-
社区稳定
目前 RN Git上有7W+的 star, 社区很活跃。插件丰富
4.React Native的缺点
参考一下,网上的论点吧
逼乎讨论,有点年头了
三.自己构建,独立渲染
1.Flutter简介
Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。
为了解决WebView性能差的问题,以React Native为代表的一类框架将最终渲染工作交还给了系统,虽然同样使用类HTML+JS的UI构建逻辑,但是最终会生成对应的自定义原生控件,以充分利用原生控件相对于WebView的较高的绘制效率。与此同时这种策略也将框架本身和App开发者绑在了系统的控件系统上,不仅框架本身需要处理大量平台相关的逻辑,随着系统版本变化和API的变化,开发者可能也需要处理不同平台的差异,甚至有些特性只能在部分平台上实现,这样框架的跨平台特性就会大打折扣。
Flutter则开辟了一种全新的思路,从头到尾重写一套跨平台的UI框架,包括UI控件、渲染逻辑甚至开发语言。渲染引擎依靠跨平台的Skia图形库来实现,依赖系统的只有图形绘制相关的接口,可以在最大程度上保证不同平台、不同设备的体验一致性,逻辑处理使用支持AOT的Dart语言,执行效率也比JavaScript高得多。
Flutter同时支持Windows、Linux和macOS操作系统作为开发环境,并且在Android Studio和VS Code两个IDE上都提供了全功能的支持。Flutter所使用的Dart语言同时支持AOT和JIT运行方式,JIT模式下还有一个备受欢迎的开发利器“热刷新”(Hot Reload),即在Android Studio中编辑Dart代码后,只需要点击保存或者“Hot Reload”按钮,就可以立即更新到正在运行的设备上,不需要重新编译App,甚至不需要重启App,立即就可以看到更新后的样式。
flutter中文网
2.Flutter架构示意图
Flutter Framework: 这是一个纯 Dart实现的 SDK,类似于 React在 JavaScript中的作用。它实现了一套基础库, 用于处理动画、绘图和手势。并且基于绘图封装了一套 UI组件库,然后根据 Material 和Cupertino两种视觉风格区分开来。这个纯 Dart实现的 SDK被封装为了一个叫作 dart:ui的 Dart库。我们在使用 Flutter写 App的时候,直接导入这个库即可使用组件等功能。
Flutter Engine: 这是一个纯 C++实现的 SDK,其中囊括了 Skia引擎、Dart运行时、文字排版引擎等。不过说白了,它就是 Dart的一个运行时,它可以以 JIT、JIT Snapshot 或者 AOT的模式运行 Dart代码。在代码调用 dart:ui库时,提供 dart:ui库中 Native Binding 实现。 不过别忘了,这个运行时还控制着 VSync信号的传递、GPU数据的填充等,并且还负责把客户端的事件传递到运行时中的代码。
3.Flutter渲染流程
4.Flutter优点
-
快速开发
毫秒级的热重载,修改后,您的应用界面会立即更新。使用丰富的、完全可定制的widget在几分钟内构建原生界面。
-
富有表现力和灵活的UI
快速发布聚焦于原生体验的功能。分层的架构允许您完全自定义,从而实现难以置信的快速渲染和富有表现力、灵活的设计。
-
原生性能
Flutter包含了许多核心的widget,如滚动、导航、图标和字体等,这些都可以在iOS和Android上达到原生应用一样的性能。
-
社区
github 4W+的 star,且稳定更新
4.Flutter缺点
-
学习成本
flutter 是用 dart 编写的,开发人员需要学习 dart语言 -
语法可读性
参考代码 -
性能没有自己说的那样高
看测试用例
UI 布局
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// final wordPair = new WordPair.random();
return new MaterialApp(
// title: 'Welcome to Flutter',
// home: new Scaffold(
// appBar: new AppBar(
// title: new Text('Welcome to Flutter'),
// ),
// body: new Center(
// // child: new Text('Hello World'),
// // child: new Text(wordPair.asPascalCase),
// child: new RandomWords(),
// ),
// ),
title: 'Startup Name Generator',
theme: new ThemeData(
primaryColor: Colors.white,
),
home: new RandomWords(),
);
}
}
class RandomWords extends StatefulWidget {
@override
createState() => new RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _biggerFont = const TextStyle(fontSize: 18);
final _saved = new Set<WordPair>();
@override
Widget build(BuildContext context) {
// final wordPair = new WordPair.random();
// return new Text(wordPair.asPascalCase);
return Scaffold(
appBar: new AppBar(
title: new Text('Startup Name Generator'),
actions: <Widget>[
new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved)
],
),
body: _buildSuggestions(),
);
}
void _pushSaved () {
Navigator.of(context).push(
new MaterialPageRoute (
builder: (context) {
final tiles = _saved.map(
(pair) {
return new ListTile (
title: new Text (
pair.asPascalCase,
style:_biggerFont,
)
);
},
);
final divided = ListTile
.divideTiles(
context: context,
tiles: tiles
)
.toList();
return new Scaffold(
appBar: new AppBar(
title: new Text('save suggestions'),
),
body: ListView(children: divided),
);
}
)
);
}
Widget _buildSuggestions() {
return ListView.builder(
padding: const EdgeInsets.all(16),
itemBuilder: (context, i){
if (i.isOdd) return new Divider();
final index = i ~/ 2;
if (index >= _suggestions.length) {
print(index);
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
},
);
}
Widget _buildRow (WordPair pair) {
final alreadySaved = _saved.contains(pair);
return new ListTile (
title: new Text(
// 'mingyang',
pair.asPascalCase,
style: _biggerFont,
),
trailing: Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
);
}
}
官方用例效果对比:
UI 测试图(官网 demo)
真机 iPhone6P 实时刷新率

使用iPhone X刷新率

相同UI效果 6P 原生swift版本刷新率:

总结:flutter 新老机型, 存在明显的性能差距, 另外在耗电和发热上面 也比native要明显许多.图就不贴了。