介绍性能检测工具 Observatory 、DevTools的基础使用及测试用例

目的

介绍Flutter的性能检测工具Observator、DevTools的如何使用,同时提供了一个Demo测试用例来检测APP性能的提升情况

工具使用

不管是vsCode还是Android Studio都提供了观测台的功能。

  • Observator
    打开的方式一般都是在terminal中输入flutter run,如果要使用真机测试则输入flutter run --profile。成功后会出现如图所示的网址,打开该网址



  • DevTools
    输入命令行flutter run --profile将程序跑起来后,打开DevTools会出现如图所示的网页,不要用Safari及其他浏览器中打开,因为DevTools只支持用Chrome浏览器打开。



    一般我们使用的都是Observatory的timeline部分。
    一般在timeline中,我们一般选用Flutter Developer的选项。出现的渲染显示我们一般会看到gpu和ui的渲染,以及重构过程。



性能优化

在性能优化之前,我们需要知道Flutter重构的逻辑。
在Android中我们知道绘制需要的三个步骤是measure、layout、draw,
在iOS中UIView绘制可参考iOS-UI绘制原理
而Flutter对应的是build、layout、paint。
Flutter的重构是基于一种标脏和重新创建的方式进行的,所以我们的性能影响一般来自于一个复杂界面的不断重建。可能你只需要修改一个很小的部分,也就是很小的一个子树需要进行修改,那么在代码没有规范的情况下,可能会出现整个界面的刷新,这样我们的性能可能就要下降了数倍。
对于我的代码而言,就是整个界面的代码都得到了重建的,但是这是基于本身代码还是简单的原因,如果代码是非常复杂的,对应用的性能就会产生极大的影响。


上文的意思用这张图来表示,本来我们只想重构的是画绿叉的子树,但是由于代码书写的原因,导致的结果是重构了画红叉的整棵树。所以代码的书写规范在性能优化上起了至关重要的作用。

代码测试

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class Test extends StatefulWidget {
  @override
  State createState() => _Test();
}

class _Test extends State {
//  int _num = 0;

//  @override
//  void initState() {
//    // TODO: implement initState
//    super.initState();
//    Timer.periodic(Duration(seconds: 1), (timer) {
//      setState(() {
//        _num = timer.tick;
//      });
//    });
//  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("test"),
      ),
      body: Column(
        children: [
          _buildTop(),
          _buildMiddle(),
          // Bottom
//          Flex(
//            direction: Axis.horizontal,
//            children: [
//              Expanded(
//                  flex: 1,
//                  child: Card(
//                    color: Colors.black26,
//                    child: Container(
//                      padding: EdgeInsets.fromLTRB(0, 100, 0, 100),
//                      child: Center(
//                        child: Text("$_num"),
//                      ),
//                    ),
//                  )),
//            ],
//          ),
          BuildBottom()
        ],
      ),
    );
  }

  Widget _buildMiddle() {
    return SizedBox(
      height: 150,
      child: ListView.builder(
        itemCount: 3,
        scrollDirection: Axis.horizontal,
        itemBuilder: (context, index) {
          return Card(
            child: Container(
              padding: EdgeInsets.fromLTRB(100, 0, 100, 0),
              child: Center(
                child: Text("Middle First"),
              ),
            ),
            color: Colors.amber,
          );
        },
      ),
    );
  }

  Widget _buildTop() {
    return Card(
      child: Text("Top"),
    );
  }
}

class BuildBottom extends StatefulWidget {
  @override
  State createState() => _BuildBottomState();
}

class _BuildBottomState extends State {
  int _num = 0;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        _num = timer.tick;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Flex(
      direction: Axis.horizontal,
      children: [
        Expanded(
            flex: 1,
            child: Card(
              color: Colors.black26,
              child: Container(
                padding: EdgeInsets.fromLTRB(0, 100, 0, 100),
                child: Center(
                  child: Text("$_num"),
                ),
              ),
            )),
      ],
    );
  }
}

上图是我测试的代码,黑框中的数据是通过定时器Timer自动更新的。

int _num = 0;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        _num = timer.tick;
      });
    });
  }

在initState()函数中,我们做了一件事情,就是一个初始化,并且让黑框中数字每1s进行一次更新。
在源码中,这个数据更新处于两种位置:Main页面、组件化的BuildBottom。

  • Main页面:在这个页面中,如果重构,就会发生我们上述所说的情况,把整个页面全部重构了。
  • 组件化的BuildBottom:将上述的更新代码转移到这个组件中,那么重构的效果就会和上述的一样,当然你还可以进行细化。


    性能优化前

    性能优化后

    通过Observatory的观测,我们能够看到两种位置进行了更新,他们重构所需要进行的步骤是完全不一样的程度,况且该Demo的页面逻辑还处于一个比较简单的状态,如果是复杂页面的话开销则会非常庞大,对性能的影响就会比较明显。

你可能感兴趣的:(介绍性能检测工具 Observatory 、DevTools的基础使用及测试用例)