Прежде всего, я хотел бы отметить, что пакет доступен для создания StatelessWidget
из функции: functions_widget
Прирост производительности не являетсяобязательно верно.Это зависит от того, как вы используете свои виджеты, в основном от того, как вы используете их для управления своим состоянием.
По умолчанию классы могут ухудшать производительность, в отличие от функций в приложении, которое не использует их мощность.
Реальный вопрос: в чем их сила?
Простой: классы могут обновляться независимо друг от друга.Функции не могут
Классы могут частично обновлять дерево виджетов.
Рассмотрим виджет, который перестраивает каждый кадр и возвращает его дочерний элемент:
class InfiniteLoop extends StatefulWidget {
const InfiniteLoop({Key key, this.child}) : super(key: key);
final Widget child;
@override
_InfiniteLoopState createState() => _InfiniteLoopState();
}
class _InfiniteLoopState extends State<InfiniteLoop> {
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
return widget.child;
}
}
Теперь, если мы поместим все наше приложение в этот виджет, что произойдет?
void main() => runApp(InfiniteLoop(child: MyApp()));
Ничего
Конечно, у вас будет один виджет, который часто перестраиваетсяв вашем дереве.Но на самом деле build
метод MyApp
будет вызываться только один раз.
Это потому, что Flutter может прервать восстановление дерева, когда экземпляр виджета не изменится.
Классы могут злоупотреблять этой оптимизацией.
Используя классы, можно хитро разделить восстановление вашего дерева виджетов на независимые части.
Нет смысла перечислять все потенциальные факторы оптимизации, которые допускает класс, поскольку их слишком много.
В следующем примере представлен виджет, который принимает int
и форматирует его в Text
.Уловка в том, что этот виджет будет перестраивать только , если int
прошло изменение:
class Counter extends StatelessWidget {
const Counter({Key key, this.value}) : super(key: key);
final int value;
@override
Widget build(BuildContext context) {
return Text(value.toString());
}
@override
bool operator ==(Object other) =>
identical(this, other) || (other is Counter && other.value == value);
@override
int get hashCode => value.hashCode;
}
Это работает, потому что Flutter использует оператор ==
, чтобы знать, должен ли виджет обновляться илинет (следовательно, почему конструктор const
является хорошим фактором оптимизации).
Это не единственное решение, но хороший пример того, что функции не могут сделать.