Flutter 主线程性能

问题描述 投票:0回答:1

无法优化超过 20,000 个项目的 UI。

在屏幕A中;从 API 响应中,我获取了产品列表(20,000 多个项目)的 JSON 文件 URL。收到 JSON 文件 URL 后,对于后台进程,我使用了隔离和计算,并且我正在对其模型进行更改并将其传递到屏幕 B。

在屏幕 B 中,我简单地使用 Listview.builder (据我所知,它经过优化以在滚动时显示项目)。 我的要求是在 UI 上同时显示所有 20,000 多个项目。我正在执行 sortBy 和 filterBy。

因此,我的用户界面变得非常滞后,有时甚至没有响应。我尝试使用隔离和计算来优化我的 UI 渲染。但我没有成功。

任何人都可以分享他们如何解决的经验或任何参考,这会很有帮助。谢谢

供参考:Flutter Channel 稳定版,3.10.6 Dart SDK 3.0.6

flutter dart user-interface listview
1个回答
0
投票

我编写了一个简单的应用程序,它从包含近 20,000 个对象的本地 JSON 中获取数据。它使用

compute
解码 JSON,并使用 ListView.builder 在 UI 滚动时动态渲染每个项目。使用肘来存储项目列表并进行过滤。该应用程序非常稳定,没有任何滞后或问题。您可以在这里查看整个源代码。

class PersonList extends StatelessWidget {
  const PersonList({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<PersonCubit, List<Person>>(
      builder: (context, items) {
        if (items.isEmpty) {
          return const Center(
            child: CircularProgressIndicator(),
          );
        }
        return ListView.builder(
          prototypeItem: PersonTile(Person.dummy()),
          shrinkWrap: true,
          itemCount: items.length,
          itemBuilder: (_, index) {
            return PersonTile(items[index]);
          },
        );
      },
    );
  }
}

class PersonTile extends StatelessWidget {
  const PersonTile(this.p, {super.key});
  final Person p;

  @override
  Widget build(BuildContext context) {
    final id = p.id;
    final color = int.parse('0xFF${id.substring(id.length - 5, id.length)}');
    return Card(
      elevation: 0,
      child: ListTile(
        title: Text(p.name),
        subtitle: _Info(balance: p.balance, email: p.email, date: p.registered),
        trailing: Icon(
          Icons.circle,
          color: p.isActive ? Colors.greenAccent : Colors.red,
        ),
        isThreeLine: true,
        tileColor: Color(color),
        onTap: () {
          Navigator.of(context).push(
              MaterialPageRoute(builder: (context) => DetailScreen(p: p)));
        },
      ),
    );
  }
}
class PersonCubit extends Cubit<List<Person>> {
  PersonCubit() : super(const []);

  void fetchItems() async {
    try {
      final s = await rootBundle.loadString('assets/data.json');
      final items = await compute(parseItems, s);
      emit(items);
    } catch (e, st) {
      // log
      log('Error fetching data!', error: e, stackTrace: st);
      emit(const []);
    }
  }

  void sortByDate() {
    emit(state.toList()..sort((a, b) => a.registered.compareTo(b.registered)));
  }

  void sortByName() {
    emit(state.toList()..sort((a, b) => a.name.compareTo(b.name)));
  }

  void sortByBalance() {
    emit(state.toList()..sort((a, b) => a.balance.compareTo(b.balance)));
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.