问题描述:
在同一个setState内的widget,其中任意一个widget发生变化,都会触发build,导致同一个setState内所有widget都重绘,
如果其他widget没有依赖发生变化的widget,这样的重绘会导致性能问题(如卡顿帧率降低、内存泄漏)。
优化方法:
1. 频繁build的widget而且其他widget不依赖与它,就把它单独封装成一个StatefulWidget,让它只在这个节点重绘,就不影响其他widget。
2. 绘制复杂的widget用const修饰,const修饰的widget被创建过以后,就不会再重建。
实例代码如下:
main.dart 源码
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '小颗粒度方式:优化频繁build绘制问题',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: '小颗粒度方式:优化频繁build绘制问题'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
get _counterWidget => [
Text("count:$_counter"),
ElevatedButton(
child: const Text('添加'),
onPressed: () {
setState(() {
_counter++;
});
})
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[..._counterWidget, OtherWidget()],//未优化
children: <Widget>[CounterWidget(), OtherWidget()], //优化
),
),
);
}
}
class OtherWidget extends StatelessWidget {
const OtherWidget({super.key});
@override
Widget build(BuildContext context) {
debugPrint("OtherWidget build");
return const Text("OtherWidget");
}
}
class CounterWidget extends StatefulWidget {
const CounterWidget({super.key});
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("count:$_counter"),
ElevatedButton(
child: const Text('添加'),
onPressed: () {
setState(() {
_counter++;
});
})
],
);
}
}
源码地址:GitHub - IBraveBegins/rebuild_draw: 最小颗粒度方式:优化频繁build绘制导致性能降低的问题