Перейти к содержанию

Оптимизация конфигурации Flatlist

Термины

  • VirtualizedList: Компонент, стоящий за FlatList (реализация в React Native концепции Virtual List).
  • Потребление памяти: Сколько информации о вашем списке хранится в памяти, что может привести к сбою приложения.
  • Отзывчивость: Способность приложения реагировать на взаимодействие. Например, низкая отзывчивость — это когда вы касаетесь компонента, а он немного ждет ответа, вместо того чтобы отреагировать сразу, как ожидалось.
  • Пустые области: Когда VirtualizedList не может отрисовывать элементы достаточно быстро, вы можете попасть в часть списка с не отрисованными компонентами, которые отображаются как пустое пространство.
  • Viewport: Видимая область содержимого, которая рендерится в пиксели.
  • Окно: Область, в которую должны быть установлены элементы, которая обычно намного больше области просмотра.

пропсы

Вот список пропсов, которые могут помочь улучшить производительность FlatList:

removeClippedSubviews

Type Default
Boolean False

Если true, виды, находящиеся за пределами области просмотра, отделяются от иерархии нативных видов.

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

Против: Имейте в виду, что эта реализация может иметь ошибки, такие как отсутствие содержимого (в основном наблюдается на iOS), особенно если вы делаете сложные вещи с преобразованиями и/или абсолютным позиционированием. Также обратите внимание, что это не экономит значительное количество памяти, так как представления не деаллоцируются, а только отделяются.

maxToRenderPerBatch

Type Default
Number 10

Это пропс VirtualizedList, который может быть передан через FlatList. Он контролирует количество элементов, отображаемых за пакет, который представляет собой следующую порцию элементов, отображаемых при каждом прокручивании.

Плюсы: Установка большего числа означает уменьшение визуальных пустых областей при прокрутке (увеличивает скорость заполнения).

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

updateCellsBatchingPeriod

Type Default
Number 50

В то время как maxToRenderPerBatch определяет количество элементов, отрисованных за один пакет, установка updateCellsBatchingPeriod указывает вашему VirtualizedList задержку в миллисекундах между пакетными отрисовками (как часто ваш компонент будет отрисовывать оконные элементы).

Плюсы: Комбинация этого параметра с maxToRenderPerBatch дает вам возможность, например, рендерить больше элементов в менее частом пакете или меньше элементов в более частом пакете.

Против: Менее частые партии могут вызвать пустые области, более частые партии могут вызвать проблемы с отзывчивостью.

initialNumToRender

Type Default
Number 10

Начальное количество элементов для рендеринга.

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

Против: Установка низкого initialNumToRender может вызвать пустые области, особенно если оно слишком мало, чтобы покрыть область просмотра при начальном рендере.

windowSize

Type Default
Number 21

Число, передаваемое здесь, является единицей измерения, где 1 эквивалентно высоте вашего окна просмотра. Значение по умолчанию равно 21 (10 видовых экранов выше, 10 ниже и один между ними).

Плюсы: Больший windowSize приведет к меньшей вероятности увидеть пустое пространство при прокрутке. С другой стороны, меньший windowSize приведет к меньшему количеству одновременно монтируемых элементов, экономя память.

Против: При большем windowSize вы будете потреблять больше памяти. При меньшем windowSize больше шансов увидеть пустые области.

Элементы списка

Ниже приведены некоторые советы относительно компонентов элементов списка. Они являются ядром вашего списка, поэтому они должны быть быстрыми.

Используйте базовые компоненты

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

Используйте легкие компоненты

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

Используйте shouldComponentUpdate.

Реализуйте проверку обновления для ваших компонентов. React's PureComponent реализует shouldComponentUpdate с неглубоким сравнением. Это дорого, потому что необходимо проверить все ваши пропсы. Если вам нужна хорошая производительность на уровне битов, создайте самые строгие правила для компонентов элементов вашего списка, проверяя только пропсы, которые потенциально могут измениться. Если ваш список достаточно прост, вы даже можете использовать

1
2
3
shouldComponentUpdate() {
  return false
}

Используйте кэшированные оптимизированные изображения

Вы можете использовать пакеты сообщества (например, react-native-fast-image от @DylanVann) для получения более производительных изображений. Каждое изображение в вашем списке — это экземпляр new Image(). Чем быстрее он достигнет хука loaded, тем быстрее ваш поток JavaScript будет снова свободен.

Используйте getItemLayout

Если все компоненты элементов вашего списка имеют одинаковую высоту (или ширину, для горизонтального списка), использование свойства getItemLayout избавляет ваш FlatList от необходимости управлять асинхронными вычислениями макета. Это очень желательная техника оптимизации.

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

Использовать keyExtractor или key

Вы можете установить keyExtractor для вашего компонента FlatList. Этот пропс используется для кэширования и как React key для отслеживания переупорядочивания элементов.

Вы также можете использовать свойство key в компоненте элемента.

Избегайте анонимных функций на renderItem

Для функциональных компонентов перенесите функцию renderItem за пределы возвращаемого JSX. Также убедитесь, что она обернута в хук useCallback, чтобы предотвратить ее повторное создание при каждом рендере.

Для компонентов класса переместите функцию renderItem за пределы функции рендеринга, чтобы она не создавалась заново при каждом вызове функции рендеринга.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const renderItem = useCallback(({item}) => (
   <View key={item.key}>
      <Text>{item.title}</Text>
   </View>
 ), []);

return (
  // ...

  <FlatList data={items} renderItem={renderItem} />;
  // ...
);

Комментарии