我正在为网站建立一个客户端,用户可以在其中以树状方式发布评论。目前,我正在使用以下命令来显示加载栏,直到加载注释为止。
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被阻塞了两倍的时间。我怀疑,它可能是由隔离区和主隔离区之间的数据传输引起的(可能发生在主线程中)。
解决这个悬而未决的问题的好方法是什么?
我想使其对用户尽可能透明(滚动列表时不加载动画)。
答案 0 :(得分:0)
我想它运行缓慢,因为您将很多对象加载到内存中。我建议您从Firebase延迟加载评论。首先显示用户只显示前20条评论,当他滚动到底部时显示另外20条评论,依此类推。
答案 1 :(得分:0)
我可以建议您不要使用将来的构建器,并且每个请求获得200条注释,因为我敢肯定您说解析数据是挂起的主要原因,因为异步下载完成后,您会尝试解析数据吗?发生在主队列上-而不是主线程上-因为flutter是单线程的,所以您可以告诉我们如何解析数据。