提高Flutter App性能的几个小技巧

遇没遇到性能问题,这些小技巧都值得关注。如果遇到了,他们可以帮助你发现和解决这些问题。如果还没有注意到,这些可以让你预防。也可以让解决这些问题的时候不至于手忙脚乱。

使用WidgetsBindingObserver来跟踪App的生命周期

使用WidgtesBindingObserver来跟踪app的生命周期。使用这个widget可以捕捉到app的pauseresume等的回调,这样可以帮助开发者快速定位到app的性能瓶颈在哪里。

dart 复制代码
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }
  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // Handle state changes here
  }
  //...
}

使用RepaintBoundary隔绝部分widget

使用RepaintBoundary widget可以把造成性能问题的那一部分widget和app的其他部分隔离。只要用这个widget把可能有性能问题的widget包起来就完成了隔离。

dart 复制代码
RepaintBoundary(
  child: MyExpensiveWidget(),
);

使用InheritedWidget传递数据

组成app的widget最终会形成一个树形结构。在传递数据的时候如果直接作为widget的参数传递不仅写起来麻烦也会造成不必要的重绘。使用InheritedWidget可以直接将数据从一个widget传到另外一个。

dart 复制代码
class MyInheritedWidget extends InheritedWidget {
  final int myData;

  MyInheritedWidget({
    Key key,
    @required this.myData,
    @required Widget child,
  }) : super(key: key, child: child);

  @override
  bool updateShouldNotify(MyInheritedWidget old) => myData != old.myData;

  static MyInheritedWidget of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }
}

多用StreamBuilder少用FutureBuilder

尽量多使用StreamBuilder,少用FutureBuilderStreamBuilder会在收到流发出的事件之后才更新,也就是必要时才更新。这样会减少绘制的次数改善性能。

dart 复制代码
StreamBuilder(
  stream: myStream,
  builder: (BuildContext context, AsyncSnapshot snapshot) {
    if (snapshot.hasData) {
      return Text(snapshot.data);
    } else if (snapshot.hasError) {
      return Text(snapshot.error);
    }
    return CircularProgressIndicator();
  },
);

列表尽量使用CustomScrollView

尽量使用CustomScrollView,因为它只会回执可见区域的widget。

dart 复制代码
CustomScrollView(
  slivers: <Widget>[
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return MyListItem(data: myData[index]);
        },
        childCount: myData.length,
      ),
    ),
  ],
);

使用AnimationController控制动画

AnimationController可以控制动画的时间和进展,可以减少widget的重绘,改善性能。

dart 复制代码
class MyAnimationWidget extends StatefulWidget {
  @override
  _MyAnimationWidgetState createState() => _MyAnimationWidgetState();
}

class _MyAnimationWidgetState extends State<MyAnimationWidget>
    with SingleTickerProvider{
    AnimationController _controller;

    @override
    void initState() {
    _controller = AnimationController(vsync: this, duration: Duration(seconds: 2));
    super.initState();
    }

    @override
    void dispose() {
    _controller.dispose();
    super.dispose();
    }

    @override
    Widget build(BuildContext context) {
        return AnimatedBuilder(
        animation: _controller,
        builder: (context, child) {
        // Use _controller.value to control the animation
        return Transform.translate(
        offset: Offset(0, _controller.value * 100),
        child: child,
        );
        },
        child: MyChildWidget(),
        );
    }
}

尽量使用Wrap代替ListView

WrapListView更加高效。因为它同样只绘制可见区域的widget。

dart 复制代码
Wrap(
  children: myChildren.map((child) => MyChildWidget(child)).toList(),
);

使用CustomPainter绘制复杂图形

CustomPainter绘制更加高效,尤其是在绘制复杂的图形或者存在嵌套的时候。

dart 复制代码
class MyCustomPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // Draw complex graphics on the canvas
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

使用PerformanceOverlay实时呈现app的性能

PerformanceOverlay可以实时图形化的展现app的性能。

dart 复制代码
PerformanceOverlay(
  enabled: true,
  overlayRect: Rect.fromLTWH(0, 0, 200, 200),
  children: [
    // Your widgets
  ],
);

使用Dart内置的Profile和Release模式测试性能

dart语言内置了ProfileRelease两个模式来测试性能。Profile模式有详细的性能数据。Release模式则是为app的性能做了优化这样来发现和解决性能问题。

bash 复制代码
flutter run --profile

Release模式:

bash 复制代码
flutter run --release

最后

此文例子其实不够详细,建议也难免有些武断。但是,作为参考可以提供一些不同的思路。

原文地址:dev.to/yatendra200...

相关推荐
小二·8 分钟前
Python Web 开发进阶实战 :AI 原生数字孪生 —— 在 Flask + Three.js 中构建物理世界实时仿真与优化平台
前端·人工智能·python
Whisper_Sy27 分钟前
Flutter for OpenHarmony移动数据使用监管助手App实战 - 网络状态实现
android·java·开发语言·javascript·网络·flutter·php
Amumu121381 小时前
Vue组件化编程
前端·javascript·vue.js
We་ct1 小时前
LeetCode 6. Z 字形变换:两种解法深度解析与优化
前端·算法·leetcode·typescript
ujainu2 小时前
Flutter + OpenHarmony 网格布局:GridView 与 SliverGrid 在鸿蒙设备内容展示中的应用
android·flutter·组件
小二·2 小时前
Python Web 开发进阶实战(终章):从单体应用到 AI 原生生态 —— 45 篇技术演进全景与未来开发者生存指南
前端·人工智能·python
龙之叶2 小时前
【Android Monkey源码解析五】- 异常处理
android·数据库
明道源码2 小时前
Android Studio AVD 模拟器的使用与配置
android·android studio
m0_637256582 小时前
vue-baidu-map添加了类型组件导致非常卡顿的问题
前端·javascript·vue.js
雨季6663 小时前
基于设备特征的响应式 UI 构建:Flutter for OpenHarmony 中的智能布局实践
javascript·flutter·ui