跨平台技术对比

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/iosYangming/article/details/84990529

跨平台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。需要自定义插件,要找原生支援
  • 举例:动画问题

canvas动画

上图是在餐饮 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的缺点

参考一下,网上的论点吧
逼乎讨论,有点年头了

破坏开源精神

Airbnb 是怎么放弃RN的? Ps被引领者放弃堪称致命

三.自己构建,独立渲染

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中文网

flutter 中文社区

2.Flutter架构示意图

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渲染流程

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要明显许多.图就不贴了。

猜你喜欢

转载自blog.csdn.net/iosYangming/article/details/84990529