Обходные пути, проблемы и советы Flutter по улучшению производительности вашего приложения Flutter

— В процессе изучения и разработки флаттер-приложения я столкнулся с рядом трудностей и проблем. В первый раз, когда я создавал приложение с помощью флаттера, основной задачей было создать работающее приложение. Но пока задачи другие. Он не только работает, но и создает приложения с хорошей производительностью. И здесь я собираю изменения, которые я сделал для улучшения производительности.

Кстати, это продолжение моих заметок прошлого месяца. Есть шесть функций, обходных путей или советов по разработке, которые я кратко изложил в своем блоге. Если вы пропустили его, вы можете прочитать его по ссылке ниже:



Содержание

Используйте SingleChildScrollView с умом
— Прекратите использовать Indexed Stack для создания постоянной нижней панели навигации
— Проблема с TextStyle
— Работайте с длинным списком
— Ссылки

Хорошо, это то, что мы будем исследовать в этом блоге. Начнем с первого:

1. Используйте SingleChildScrollView с умом

Если вы думаете, что Столбец + SingleChildScrollView = ListView (с направлением вертикальной оси), вы ошибаетесь.

На первый взгляд поведение такое же. ListView — виджет с возможностью прокрутки. Столбец — это виджет, который отображает дочерние элементы в вертикальном направлении. И в обычной практике, когда нам нужно сделать Столбец прокручиваемым, самый простой способ — обернуть его SingleChildScrollView. Хотя это обычная практика, это не означает, что это правильная практика использования.

Посмотрим сравнение. Вот у меня 50 виджетов Карточка.

List<Widget>.generate(50,(int index)=> MyCardWidget());

Как мы видим на двух изображениях выше, они совершенно разные. Итак... когдау вас есть список дочерних элементов и вам не требуется поперечное сжатие, например, список с прокруткой, который всегда равен ширине экрана, рассмотрите ListView.Не используйте SingleChildScrollView. В этом случае использование ListView намного эффективнее.

Почему?

Простая логика: когда у вас есть виджет с динамическим размером, его рендеринг будет стоить дороже, чем виджет со статическим размером. Пример: виджет с индексом 1 и индексом 11 имеет разную ширину в зависимости от длины текста внутри виджета. Flutter сначала вычисляет длину текста, а затем присваивает размеры карточке.

В то время как в Списке все виджеты Карточка имеют одинаковую ширину. Нет необходимости вычислять каждую карточку.

Дорого, что означает потребление большего количества ресурсов. Это приводит к снижению производительности.

SingleChildScrollView полезен, когда у вас есть один блок, который обычно полностью виден. Рекомендуется использовать SingleChildScrollView, чтобы обойти предупреждение о переполнении виджета. Обычно это происходит, когда размер экрана устройства слишком мал.

Если у вас длинный список виджетов, рассмотрите возможность использования ListView. Это потому, что ListView создает дочерние элементы по требованию.

Создание дочерних элементов по запросу означает, что создаются только дочерние элементы, видимые на экране. Например, если у нас есть 1000 виджетов, но на экране помещается только 8 виджетов. Тогда конструктор создаст только 8 видимых виджетов. Каждый раз, когда пользователь прокручивает список, создается новый дочерний элемент. Старые дочерние элементы, которых больше не видно на экране, будут уничтожены.

НЕ рекомендуется заключать ListViewв Columnс SingleChildScrollView.

// Bad Practice
SingleChildScrollView(
 child:Column(
    children: [
       ListView.builder(),
       SizedBox(),
       ListView.builder(),
       ....

Конструктор ListView. в приведенном выше коде больше не будет повышать производительность. Все дочерние виджеты будут созданы одновременно. Если ожидается, что область просмотра будет содержать контент, выходящий за пределы размеров экрана, то SingleChildScrollView будет очень дорогим.

2. Прекратите использовать IndexedStack для создания постоянной панели BottomNavbar

Если вам нужен код, чтобы ваша BottomNavigationBar сохранялась на всех экранах, вы можете найти некоторые обходные пути, используя виджет IndexedStack. Это хорошее и простое решение, и я использовал его раньше. Однако это имеет довольно плохой эффект, когда мы открываем приложение в первый раз. Давайте посмотрим на структуру дерева виджетов при использовании IndexedStack.

С помощью этого метода у нас будет один родительский виджет с BottomNavigationBar. Экраны будут располагаться один за другим как дочерние. Дочерние виджеты будут отображаться на основе выбранного индекса.

тогда что не так?

Вот как я разбираюсь в этом вопросе. Когда я открываю приложение, оно сначала переходит к виджету BaseLayout (согласно имени моего класса). И дело в том, что «ВСЕ» дочерние виджеты будут выполняться флаттером. Не только выбранный индекс.

Пример: у меня есть 10 дочерних виджетов. Page1(), Page2(), Page3() и так далее…
начальный выбранный индекс = 0 . В этом случае на экране будет отображаться Page1().

Я предполагаю, что будет выполнен только класс Page1() class. Однако флаттер выполнил с Page1() по Page10().

Давайте докажем это

Я печатаю строку внутри initState каждого дочернего элемента. Я возьму один пример функции на моем домашнем экране. Как код ниже:

@override
void initState() {
  print("init home screen...........");
  super.initState();
  fetchApi();
}

Я также печатаю одну и ту же строку для всех детей. См. изображение ниже, все функции initState выполняются print «init ${nameScreen}……….»

Представьте, что у вас в детстве есть экран десятков в IndexedStack. Вашему флаттер-приложению потребуется некоторое время, чтобы выполнить все операции.

Для этой проблемы моим текущим решением является замена IndexedStackна переключатель-кейс. С помощью этого метода будет выполняться только выбранный индекс. См. код ниже:

3. Проблема с TextStyle

Я нашел эту проблему из вопроса на StackOverflow. Цвет фона TextStyle игнорируется пробелом (код asci = 32) в конце строки. И вот как я это исследовал.

Container(
  color: Colors.amber,
  child: const Text('   Foo    ',
      style: TextStyle(
      backgroundColor: Colors.blue,
      color: Colors.white,
     ),
  ),
),

Смотрите изображение ниже:

Я обернул виджет Текст в Контейнер и установил желтый цвет фона. А для Textstyle я установил синий цвет фона.

  • Первая Foo : синий фон применяется до последней буквы «о». Первоначально я предполагал, что пробелы не отображаются.
  • Второй Foo : доказывает, что отрисовываются пробелы. О чем свидетельствует желтый цвет фона, присвоенный последнему пробелу в виджете Текст.
  • третье: я добавил невидимый символ > в виджет Текст, и фон был применен.
  • и, наконец, только с пробелами: синий фон не применяется

На самом деле, этот вопрос до сих пор нерешен. Если вам действительно нужно добавить место для виджета Текст , вы можете воспользоваться приведенными выше советами, добавив невидимый символ в последнюю строку. Другой вариант — использовать виджет TextSpan и добавить к нему горизонтальные отступы.

Недурно, чтобы привлечь внимание участников. Вы можете найти нерешенную проблему здесь:



4. Работа с длинным списком

В первом разделе мы сравнили SingleChildScrollView с виджетом ListView. А теперь давайте подробнее поговорим об использовании виджета ListView.

Стандартный конструктор ListView хорошо подходит для небольших списков. Для работы со списками, содержащими большое количество элементов, лучше всего использовать конструктор ListView.builder.

По умолчанию конструктор ListView требует создания всех элементов одновременно. Но конструктор ListView.builder создает элементы по мере их прокрутки на экране.

пример: если у вас есть виджет списка длиной 10 000, рассмотрите возможность использования ListView.builder. Потому что это повлияет на производительность приложения при рендеринге пользовательского интерфейса. Тысячи виджетов — это очень длинный список. Было бы дорого делать все предметы сразу. Конструктор ListView.builder будет обрабатывать механизм создания виджета по запросу.

Честно говоря, есть много проблем, обходных путей и советов, которыми я хочу поделиться. Но у этих 4 тем есть длинное объяснение. Поэтому я решил написать их в моей следующей статье. Если вам понравилась эта статья, ждите моей следующей флаттер-заметки. И, наконец, спасибо за чтение. Если у вас есть какие-либо вопросы или мнения, не стесняйтесь оставлять комментарии ниже. Я был бы рад открыть любую дискуссию.

Ссылка