Почему желательно не использовать KISS и DRY в билде Flutter
Что проверяют
Понимаете ли вы, как Flutter решает, что перестраивать. Вопрос провокационный: проверяют, отличаете ли вы «вынес кусок разметки в метод» от «вынес в отдельный виджет», потому что для фреймворка это совершенно разные вещи.
Как отвечать
Сначала снимите провокацию: KISS и DRY никто не отменяет, отменяется их наивное применение внутри build. Привычный приём «повторяющийся кусок вынесу в приватный метод _buildHeader()» выглядит как борьба с дублированием, но метод не создаёт отдельный узел в дереве элементов. Он подставляется в тот же build и пересобирается целиком при каждой перестройке родителя.
Отдельный класс-виджет ведёт себя иначе: у него свой элемент, и если конструктор const, а параметры не изменились, Flutter пропускает поддерево и его build не вызывает вовсе.
// перестроится вместе с родителем
Widget _buildHeader() => const Text('Заголовок');
// получит свой узел и может быть пропущен
class Header extends StatelessWidget {
const Header({super.key});
@override
Widget build(BuildContext context) => const Text('Заголовок');
}Отсюда практика: держать setState как можно ниже по дереву, помечать неизменяемые части const, точечные обновления делать через ValueListenableBuilder или параметр child у AnimatedBuilder, который строится один раз и передаётся внутрь готовым.
Где спотыкаются
Объясняют это тем, что мелкие виджеты тормозят. Наоборот: чем мельче и постояннее виджеты, тем больше поддеревьев фреймворк переиспользует. Тормозит крупный build, который пересобирает всё сразу.
Второе: обобщают виджет до неузнаваемости ради DRY. Флаги вроде isCompact и showIcon плодят ветвления, из-за которых меняется тип возвращаемого поддерева, и Flutter теряет состояние при переключении. Два честных виджета тут дешевле одного универсального.
Третье: путают дорогое построение и дорогую отрисовку. build создаёт лёгкие описания, а реальная цена часто в Opacity, ClipRRect и тенях, которые заставляют композитор делать отдельный слой. Это видно в профилировщике, угадывать не нужно.