[译] 测试原生,Flutter 和 React Native 移动开发之间的性能差异。

栏目: 服务器 · 发布时间: 6年前

内容简介:确定你们公司的移动应用程序是真正的原生应用还是采用跨平台方法实现(如React Native 或Flutter)是一个很艰难的决定。经常会考虑的一个因素是速度问题 —— 我们都普遍认为大多数跨平台方法比原生方法慢,但是很难说出具体的数字。因此,当我们考虑性能时,我们常常会靠直觉,而不是具体的数据。因为希望在上述性能分析中添加一些结构,以及对 Flutter 如何实现其性能承诺的兴趣,我决定构建一个非常简单的应用程序分别对应原生版本,React Native 版本以及 Flutter 版本,进而比较他们的性

确定你们公司的移动应用程序是真正的原生应用还是采用跨平台方法实现(如React Native 或Flutter)是一个很艰难的决定。经常会考虑的一个因素是速度问题 —— 我们都普遍认为大多数跨平台方法比原生方法慢,但是很难说出具体的数字。因此,当我们考虑性能时,我们常常会靠直觉,而不是具体的数据。

因为希望在上述性能分析中添加一些结构,以及对 Flutter 如何实现其性能承诺的兴趣,我决定构建一个非常简单的应用程序分别对应原生版本,React Native 版本以及 Flutter 版本,进而比较他们的性能。

测试应用

我构建的应用程序尽可能简单,同时确保至少仍能提供一些信息。它是一个计时器应用 —— 具体来说,该应用程序显示随着时间的推移计数的一团文本。它显示自应用程序启动以来经过的分钟数、秒数和毫秒数。相当简单。

下面是它初始状态的样子:

[译] 测试原生,Flutter 和 React Native 移动开发之间的性能差异。

这是 1 分钟 14 秒 890 毫秒后的样子:

[译] 测试原生,Flutter 和 React Native 移动开发之间的性能差异。

铆。

但是为什么选计时器?

我选择计时器应用有两个原因:

  1. 它在每个平台上都很容易开发。这个应用程序的核心是某种类型的文本视图和重复计时器,很容易翻译成三种不同的语言和堆栈。
  2. 它表明了底层系统在屏幕上绘制内容的效率。

让我们看一看代码

幸运的是,这个应用足够小,我可以直接在这里添加相关代码。

原生 Android 应用

以下是原生 Android 应用的 MainActivity:

class MainActivity : AppCompatActivity() {

  val timer by lazy {
    findViewById<TextView>(R.id.timer)
  }

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    initTimer()
  }

  private fun initTimer() {
    val startTime = elapsedRealtime()
    val handler = Handler()
    val runnable: Runnable = object: Runnable {
      override fun run() {
        val timeDifference = elapsedRealtime() - startTime
        val seconds = timeDifference / 1000
        val minutes = seconds / 60
        val leftoverSeconds = seconds % 60
        val leftoverMillis = timeDifference % 1000 / 10
        timer.text = String.format("%02d:%02d:%2d", minutes, leftoverSeconds, leftoverMillis)
        handler.postDelayed(this, 10)
      }
    }

    handler.postDelayed(runnable, 1)
  }
}
复制代码

React Native

这是 React Native 应用程序的 App.js 文件:

export default class App extends Component {

  render() {
    return (
      <View style={styles.container}>
        <Timer />
      </View>
    );
  }
}

class Timer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      milliseconds: 0,
      seconds: 0,
      minutes: 0,
    }

    let startTime = global.nativePerformanceNow();
    setInterval(() => {
      let timeDifference = global.nativePerformanceNow() - startTime;
      let seconds = timeDifference / 1000;
      let minutes = seconds / 60;
      let leftoverSeconds = seconds % 60;
      let leftoverMillis = timeDifference % 1000 / 10;
      this.setState({
        milliseconds: leftoverMillis,
        seconds: leftoverSeconds,
        minutes: minutes,
      });
    }, 10);
  }

  render() {
    let { milliseconds, seconds, minutes } = this.state;
    let time = sprintf("%02d:%02d:%2d", minutes, seconds, milliseconds);
    return (
      <Text>{time}</Text>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  }
});
复制代码

Flutter

最后这是我们的 Flutter main.dart 文件:

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _startTime = new DateTime.now().millisecondsSinceEpoch;
  int _numMilliseconds = 0;
  int _numSeconds = 0;
  int _numMinutes = 0;

  @override
  void initState() {
    super.initState();
    Timer.periodic(new Duration(milliseconds: 10), (Timer timer) {
      int timeDifference = new DateTime.now().millisecondsSinceEpoch - _startTime;
      double seconds = timeDifference / 1000;
      double minutes = seconds / 60;
      double leftoverSeconds = seconds % 60;
      double leftoverMillis = timeDifference % 1000 / 10;
      setState(() {
        _numMilliseconds = leftoverMillis.floor();
        _numSeconds = leftoverSeconds.floor();
        _numMinutes = minutes.floor();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new Center(
          child: new Text(
            sprintf("%02d:%02d:%2d", [_numMinutes, _numSeconds, _numMilliseconds]),
          ),
        )
    );
  }
}
复制代码

每个应用程序都遵循相同的基本结构 —— 它们都有一个计时器,每 10 毫秒重复一次,并重新计算自计时器启动以来经过的分钟数、秒和毫秒数。

我们如何测量性能?

对于那些不熟悉 Android 开发的人来说,Android Studio 是构建 Android 应用程序的首选编辑器/环境。它还附带了一系列有用的分析器来分析你的应用程序 —— 具体来说,它有一个 CPU 分析器,一个内存分析器和一个网络分析器。所以我们将使用这些分析器来判断性能。所有测试都在 Thoughtbot 的 Nexus 5X 和我自己的第一代 Google Pixel 上运行。React Native 应用程序将在 --dev 标志设置为 false 的情况下运行,Flutter 应用程序将在 profile 配置中运行,以模拟发布应用程序而不是 JIT 编译的调试应用程序。

给我看数据!

到了这篇文章最有趣的部分了。让我们看一下在 Thoughtbot 办公室的 Nexus 5X 上运行时的结果。

Nexus 5X 上面原生应用的结果

[译] 测试原生,Flutter 和 React Native 移动开发之间的性能差异。

Nexus 5X 上面 React Native 应用的结果

[译] 测试原生,Flutter 和 React Native 移动开发之间的性能差异。

Nexus 5X 上面 Flutter 应用的结果

[译] 测试原生,Flutter 和 React Native 移动开发之间的性能差异。

这些结果首先表明的是,当涉及到性能时,原生 Android 应用程序胜过 React Native 和 Flutter 应用程序可不是一点半点。原生应用程序上的 CPU 使用率不到 Flutter 应用程序的一半,与 React Native 应用程序相比,Flutter 占用的 CPU 更少一些,但是差别不大。原生应用程序的内存使用率同样很低,并且在 React Native 和 Flutter 应用程序上内存使用率都有所增加,不过这次 React Native 应用表现得比 Flutter 应用更好。

下一个有趣的内容是 React Native 和 Flutter 应用程序在性能上是如此 相近 。虽然这个应用程序无疑是微不足道的,但我原本以为 JavaScript 桥接器会受到更多的影响,因为应用程序如此快速地通过该桥接器发送了如此多的消息。

现在让我们看看在 Pixel 上测试时的结果。

Pixel 上面原生应用的结果

[译] 测试原生,Flutter 和 React Native 移动开发之间的性能差异。

Pixel 上面 React Native 应用的结果

[译] 测试原生,Flutter 和 React Native 移动开发之间的性能差异。

Pixel 上面 Flutter 应用的结果

[译] 测试原生,Flutter 和 React Native 移动开发之间的性能差异。

所以,我立马就对 Pixel 上显然更高的 CPU 占用感到惊讶。它肯定是比 Nexus 5X 更强大(在我看来就是更流畅)的手机,所以我自然而然假设同一应用程序的 CPU 利用率将_更低_,而不是更高。我可以理解为什么内存使用会更高,因为 Pixel 上有更大的内存空间而且 Android 上遵循一条“使用它或者浪费它”的策略来保持内存。如果读者中有任何人知道的话,我很想了解一下为什么 CPU 使用率会更高!

第二个有趣的收获是,Flutter 和 React Native 与原生应用相比在他们的优势和劣势方面有了_更明显_的差别。React Native 只比原生应用程序占用的内存略微高一点,而 Flutter 的内存使用率比原生应用程序高出近 50%。另一方面,Flutter 应用程序更接近于原生应用程序的 CPU 使用率,而 React Native 应用程序则难以保持低于 30% 的 CPU 使用率。

最重要的是,我对 5X 和 Pixel 之间结果的 差异之大 感到惊讶。

结论

我可以很有信心地说原生 Android 应用的性能优于 React Native 应用或 Flutter 应用。不过,我_没有_信心说 React Native 应用将表现得比 Flutter 应用更好,反之亦然。还需要做 更多 的测试才能弄清楚 Flutter 是否能真正提供比 React Native 更高的真实性能。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

疯狂的站长

疯狂的站长

温世豪 / 清华大学出版社 / 2010年05月 / 29.00元

受全球性金融危机的影响,就业变得越来越困难,众多青年,包括大学毕业生,无不感到就业的巨大压力,站长这一职业不但创业门槛低,而且还自由自在。其实,搭建一个网站是相当简单的,但要成为一名成功的站长则不那么容易。 本书作者是一名站长,从事互联网相关工作已十余年,自已也在经营一个知名网站,积累了大量网站运营经验。作者结合自身真实的“疯狂”创业经历,以平实、通俗的语言讲述如何从零开始起步,最终成为一名......一起来看看 《疯狂的站长》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

SHA 加密
SHA 加密

SHA 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试