Это законная оптимизация.Фактически вы можете сделать то же самое с виджетами, зависящими от состояния (в сочетании с didUpdateWidget
).Тем не менее, выигрыш незначителен.
Виджеты чрезвычайно легки, а Дарт оптимизирован для множества микроинстанций.
И с этим подходом есть одна проблема: вы теряете горячую перезагрузку.
Повторное использование старых экземпляров виджетов все еще довольно полезно.Как будто экземпляр виджета не изменяется, Flutter прерывает сборку поддерева.
Это очень часто используется в анимациях, чтобы не перестраивал все дерево виджетов каждые кадры.Типичным примером будет AnimatedBuilder
(но все XXTransition
следуют той же логике)
Animation animation;
AnimatedBuilder(
animation: animation,
child: Text('Foo'),
builder: (context, child) {
return Align(
alignment: Alignment(.5, animation.value),
child: child,
);
},
);
Здесь это добровольно повторно использует экземпляр child
, так что метод сборки Text
не вызываетсяснова.
Итак, я должен это делать или нет?
Ну, да, и нет.Всегда круто оптимизировать ваше приложение.Но вместо того, чтобы делать это с помощью переменных, есть лучший способ: конструкторы const.
Чтобы повторно использовать ваш пример, вы можете извлечь свое "всегда одинаковое" дерево виджетов в пользовательский виджет с помощью конструктора const:
class _Foo extends StatelessWidget {
const _Foo({Key key}): super(key: key);
@override
Widget build(BuildContext context) {
return Text(
'Oeschinen Lake Campground',
style: TextStyle(
fontWeight: FontWeight.bold,
),
);
}
}
, а затем используйте его в своем методе build
:
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.only(bottom: 8.0),
child: const _Foo(),
);
}
Таким образом вы получите преимущества кэширования экземпляра виджета.НО вы не теряете горячую перезагрузку.
Идеально верно?