- 避免不必要的重绘
- 使用const和final:
- 在构建Widget树时,尽量使用
const
和final
修饰Widget。const
Widgets在编译时就确定,不会在运行时改变,Flutter可以更高效地复用它们。例如,const Text('固定文本')
,这样的文本Widget不会因为父Widget的状态变化而重绘。
final
变量也是不可变的,对于一些不会改变的对象,使用final
声明有助于性能提升。
- 局部构建:
- 只在真正需要更新的部分进行构建。例如,如果一个复杂的页面有一个列表和一些固定的标题,当列表数据更新时,只重建列表部分,而不是整个页面。可以使用
AnimatedBuilder
或IndexedStack
等Widget来实现局部构建。例如,使用AnimatedBuilder
来包裹需要根据动画状态更新的部分:
AnimatedBuilder(
animation: animationController,
builder: (context, child) {
return Container(
// 这里只构建与动画相关的部分
);
},
child: child,
);
- 使用
AutomaticKeepAliveClientMixin
:
- 对于那些需要保持状态且不需要频繁重建的Widget,例如分页中的各个页面,可以使用
AutomaticKeepAliveClientMixin
。这样,当这些Widget被移出屏幕后,不会被销毁重建,下次再显示时可以保持原来的状态,避免了不必要的重绘。例如:
class MyPage extends StatefulWidget {
@override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return Container();
}
}
- 合理利用
shouldRebuild
方法
- 对比新旧状态:
- 在
shouldRebuild
方法中,通过对比新旧状态来判断是否真的需要重建。例如,如果StatefulWidget的状态是一个包含多个属性的类,可以只对比那些真正影响Widget外观的属性。
class MyComplexWidget extends StatefulWidget {
MyComplexWidget({Key key}) : super(key: key);
@override
_MyComplexWidgetState createState() => _MyComplexWidgetState();
}
class _MyComplexWidgetState extends State<MyComplexWidget> {
MyData _data;
@override
void initState() {
_data = MyData();
super.initState();
}
@override
bool shouldRebuild(_MyComplexWidgetState oldState) {
// 只对比需要关注的属性
return oldState._data.someImportantProperty != _data.someImportantProperty;
}
@override
Widget build(BuildContext context) {
return Container();
}
}
class MyData {
int someImportantProperty;
}
- 避免复杂计算:
shouldRebuild
方法中的逻辑应该尽量简单高效。因为这个方法会在每次状态变化时被调用,如果其中包含复杂的计算,可能会影响性能。例如,不要在shouldRebuild
中进行网络请求或复杂的数据库查询等操作。