Как построить сложный виджет без блокировки рендеринга интерфейса? - PullRequest
0 голосов
/ 11 апреля 2019

Я создаю клиент для веб-сайта, где пользователи могут оставлять комментарии в виде дерева.В настоящее время я использую следующее для отображения панели загрузки, пока комментарии не будут загружены.

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;
                  }
              }
            },
          )

Но это еще медленнее, пользовательский интерфейс блокируется вдвое больше времени.Я подозреваю , что это может быть вызвано передачей данных между изолятом и главным изолятом (что может произойти в главном потоке).

Что было бы хорошим способом решить эту зависаниеПроблема?

Я бы хотел сделать ее максимально прозрачной для пользователя (без анимации загрузки при прокрутке списка).

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

Могу ли я предложить вам не использовать будущего компоновщика и получать 200 комментариев на запрос, поскольку, как я уверен, вы сказали, что анализ данных является основной причиной зависания, поскольку после завершения асинхронной загрузки происходит попытка анализа данных. что происходит в основной очереди, а не в основном потоке, так как флаттер однопоточный, так что вы можете показать нам, как вы анализируете данные.

0 голосов
/ 11 апреля 2019

Я полагаю, это работает медленно, потому что вы загружаете много объектов в память.Я предлагаю вам сделать ленивую загрузку комментариев из firebase.Сначала показывать пользователю только первые 20 комментариев, а когда он прокручивает вниз, показывают еще 20 комментариев и т. Д.

...