提高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...

相关推荐
并不会1 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
衣乌安、1 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜1 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师1 小时前
CSS的三个重点
前端·css
姑苏风2 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
耶啵奶膘2 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^4 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie4 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic5 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
数据猎手小k5 小时前
AndroidLab:一个系统化的Android代理框架,包含操作环境和可复现的基准测试,支持大型语言模型和多模态模型。
android·人工智能·机器学习·语言模型