Код-ревью Middle Производительность обновлено
Код-ревью: экран каталога
Вопрос
Экран каталога с поиском. Найдите проблемы производительности.
class _CatalogState extends State<Catalog> {
String query = '';
@override
Widget build(BuildContext context) {
final filtered = widget.products
.where((p) => p.title.toLowerCase().contains(query.toLowerCase()))
.toList()
..sort((a, b) => a.title.compareTo(b.title));
return Column(children: [
TextField(onChanged: (v) => setState(() => query = v)),
Expanded(
child: ListView(
children: [for (final p in filtered) ProductTile(p)],
),
),
Opacity(opacity: 0.9, child: Footer(stats: computeStats(widget.products))),
]);
}
}
Коротко
Главная идея: build должен быть дешёвым. Вычисления делаются при изменении данных, а не при каждой отрисовке; длинные списки ленивые; setState охватывает минимальное поддерево; дорогие эффекты отрисовки заменяются простыми.
Что должен найти ревьюер
- Производительностьстрока 6Фильтрация и сортировка всего каталога в
buildна каждый символ ввода. Считать при изменении запроса (с debounce), для больших данных в изоляте. - Производительностьстрока 9Сортировка всего списка каждый раз: каталог можно отсортировать один раз заранее, фильтрация сохраняет порядок.
- Производительностьстрока 11
setStateна весь экран при каждом символе перестраивает иFooter. Вынести поле и список в отдельный виджет или подписку. - Производительностьстрока 13
ListView(children:)строит все элементы. НуженListView.builder. - Стильстрока 14У
ProductTileнет ключа иconst: при фильтрации элементы сопоставляются по позиции. - Производительностьстрока 17
computeStatsпо всему каталогу на каждом перестроении иOpacityнад футером. Посчитать один раз, а прозрачность задать цветом.
Разбор
Главная идея: build должен быть дешёвым. Вычисления делаются при изменении данных, а не при каждой отрисовке; длинные списки ленивые; setState охватывает минимальное поддерево; дорогие эффекты отрисовки заменяются простыми.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.