1.不要将你的界面组件切分到方法中
如:
class MyHomePage extends StatelessWidget {
Widget _buildHeaderWidget() {
return Container(...);
}
Widget _buildBodyWidget() {
return Container(...);
}
Widget _buildFooterWidget() {
return Container(...);
}
@overrider
Widget build(BuildContext context) {
return Scaffold(
body:Column(
children:[
_buildHeaderWidget(),
_buildBodyWidget(),
_buildFooterWidget(),
],
),
);
}
}
每次我们改变或刷新整体的widget时,分割在method里的widget也会被重构一次,这导致了对cpu资源的浪费。
使用提取界面组件为自定义类的方式代替
如:
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
_HeaderWidget(),
_BodyWidget(),
_FooterWidget(),
],
),
);
}
}
class _HeaderWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(...);
}
}
class _BodyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(...);
}
}
class _FooterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(...);
}
}
Stateful/Stateless widget 有一种特别的缓存机制(基于key、widget type、属性),这使得它们只会在必要的时候重构。
这一点,我感觉,如果你不设置key,好像还是会重构。
2.不要反复地重构所有的widgets
核心思想是指,尽量只重构必要的widget。
少用setState
替代方案
ValueNotifier
class _MyHomePageState extends State<MyHomePage> {
final ValueNotifier notifier = ValueNotifier(false);
@override
void dispose(){
notifier.dispose();
super.dispose;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ValueListenableBuilder(
valueListenable: notifier,
child: _Child(),
builder: (_,v,child) => Offstage(
offstage: v,
child: child,
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
notifier.value = !notifier.value;
},
),
);
}
}
class _Child extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('_Child build');
return Center(child: Text('hello'),);
}
}
当ValueNotifier
的value
发生变化时,会自动通知ValueListenableBuilder
执行builder
传入的回调,简单易用。
如果不使用ValueListenableBuilder
的child
属性,而是直接将_Child()
构建在builder
回调里,_Child
将在每次notifier
的值改变时被重构。
provider框架中就继承了ValueNotifier的父类 ChangeNotifier
将不变的widget用const
修饰
抓住核心思想(减少不必要的重构)就行了。
3.在使用长列表时,尽可能的使用itemExtent
属性
这一点其实在任何时候都适用,尽可能的给你的widget一个大小,可以节省cpu计算widget大小的时间。
4.不要再AnimatedBuilder中重构不必要的widget
AnimatedBuilder的重构方式和上面ValueListenableBuilder类似,都是会执行builder回调。
5.不要使用Opacity特别是在动画里
Opacity用在动画里时,会使界面每一帧都重构。这一点闲鱼团队也提过。
替代方案