如何在不阻止UI渲染的情况下构建复杂的小部件?

时间:2019-04-11 12:51:39

标签: dart flutter flutter-layout

我正在为网站建立一个客户端,用户可以在其中以树状方式发布评论。目前,我正在使用以下命令来显示加载栏,直到加载注释为止。

FutureBuilder(
            future: fetchComments(this.storyId),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                case ConnectionState.active:
                case ConnectionState.waiting:
                  return LinearProgressIndicator();
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    final MissingRequiredKeysException myError = snapshot.error;
                    return Text('Error: ${myError.missingKeys}');
                  } else {
                    final api.Comment comment = snapshot.data;

                    return Expanded(child: Comment(comment.comments));
                  }
              }
            }
)

当大约有200条评论时,此方法效果很好,但如果超过此数量,则加载栏会“挂起”一段相当长的时间。

我认为构建Comment小部件会花费大量时间,因为它可以深度嵌套。

为了避免挂起主线程,我修改了代码以在Isolate内创建窗口小部件:

FutureBuilder(
            future: compute<int, Widget>(
                buildComments, this.storyId),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                case ConnectionState.active:
                case ConnectionState.waiting:
                  return LinearProgressIndicator();
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    final ArgumentError myError = snapshot.error;
                    return Text('Error: ${myError.message}');
                  } else {
                    final Widget comments = snapshot.data;

                    return comments;
                  }
              }
            },
          )

但这甚至更慢,UI被阻塞了两倍的时间。我怀疑,它可能是由隔离区和主隔离区之间的数据传输引起的(可能发生在主线程中)。

解决这个悬而未决的问题的好方法是什么?

我想使其对用户尽可能透明(滚动列表时不加载动画)。

2 个答案:

答案 0 :(得分:0)

我想它运行缓慢,因为您将很多对象加载到内存中。我建议您从Firebase延迟加载评论。首先显示用户只显示前20条评论,当他滚动到底部时显示另外20条评论,依此类推。

答案 1 :(得分:0)

我可以建议您不要使用将来的构建器,并且每个请求获得200条注释,因为我敢肯定您说解析数据是挂起的主要原因,因为异步下载完成后,您会尝试解析数据吗?发生在主队列上-而不是主线程上-因为flutter是单线程的,所以您可以告诉我们如何解析数据。