Использование памяти становится все выше и выше, пока я прокручиваю Flatlist, и память не освобождается, когда я прекращаю прокрутку (React Native)

Я использую Flatlist и SectionList в своем родном проекте, и у меня более 300 строк данных. Однако я обнаружил серьезную проблему: когда я продолжаю прокручивать вниз и вверх, использование памяти становится все выше и выше. Как я могу решить эту проблему? Или как освободить память?

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

Например,

1. Я использовал Pure.component или shouldcomponentUpdate

2. Я использовал некоторые реквизиты Flatlist и SectionList

initialNumToRender={9}
windowSize={10}
maxToRenderPerBatch={2}
removeClippedSubviews={true}
disableVirtualization={true}
getItemLayout={this.getItemLayout}
keyExtractor={(item, index) => item[0]}
extraData={this.state}

Есть ли другие решения, которые могут помочь мне решить проблемы? Большое спасибо!


comment
попробуйте стиль overflow: 'hidden' для элемента строки.   -  person Melih Mucuk    schedule 26.09.2018
comment
эй У тебя есть какое-нибудь решение по этому поводу?   -  person Mayuresh Patil    schedule 15.04.2019


Ответы (1)


disableVirtualization={true} в основном отключает функции виртуализации, которые предлагает FlatList, поэтому я не рекомендую его, если есть проблемы с памятью. Так что я бы начал с удаления этой опоры.

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

Параметр windowSize FlatList определяет, сколько «невидимых» элементов будет отображаться. Если вы установите для windowSize значение «1», будут отображаться только видимые элементы (попробуйте это и посмотрите, что произойдет, когда вы прокрутите FlatList). Размер окна "21" (значение по умолчанию) будет отображать видимые элементы плюс 10 "окон" слева и справа (или сверху и снизу) от видимой области. Таким образом, если размер окна составляет, скажем, 1000 пикселей, любые элементы, которые сейчас невидимы, но находятся на расстоянии менее 10000 пикселей от видимой области, будут отрисованы FlatList заранее.

Вот как я бы подошел к проблеме:

  • Во-первых, я бы установил для windowSize очень большое значение (например, 100), чтобы убедиться, что все 300+ строк будут сохранены в памяти. Вы можете открыть приложение и подождать некоторое время, пока все элементы не будут отрисованы (если у вас есть более 300 элементов и для параметра maxToRenderPerBatch установлено значение 2, это означает, что FlatList потребуется 150+ «циклов», чтобы завершить рендеринг всего, поэтому это может занять некоторое время. . Вы также можете, только ради этого эксперимента, установить для initialNumToRender очень большое число (например, 1000), чтобы при рендеринге списка вы знали, что он уже полностью отрендерен. Но, скорее всего, приложение зависнет на несколько секунд, прежде чем это произойдет). Когда весь список будет готов, посмотрите, сколько памяти использует ваше приложение. В этом сценарии прокрутка вверх и вниз не должна увеличивать использование памяти, потому что все уже есть в пользовательском интерфейсе :-). Обратите внимание на этот объем памяти, так как он будет вашим базовым уровнем.
  • Во-вторых, я бы установил windowSize наименьшее возможное число (например, 1). Теперь, когда вы открываете экран с таким огромным объемом данных, React будет отображать только то, что видно на экране. Использование памяти должно быть намного меньше, чем в предыдущем случае. Однако при прокрутке React будет постоянно уничтожать и создавать новые элементы пользовательского интерфейса из-за ограниченного размера окна. Если чем больше вы прокручиваете, тем больше памяти используется (и она никогда не возвращается назад, даже если вы на некоторое время прекращаете прокрутку), то, вероятно, в ваших визуальных компонентах есть утечка памяти, которую необходимо исправить. Если это так, медленная прокрутка до конца списка и медленная прокрутка до самого верха может даже привести к использованию большего объема оперативной памяти, чем в первом случае.

Утечки памяти бывает сложно найти, поэтому я надеюсь, что простая настройка размера окна и нескольких других параметров даст нужные вам результаты. Если есть утечки памяти, это интересная статья, которую я недавно прочитал: https://blog.swmansion.com/hunting-js-memory-leaks-in-react-native-apps-bd73807d0fde

Кроме того, избегайте проверки использования ОЗУ с помощью отладочных сборок: они не только используют больше памяти, но и средства отладки (такие как console.log и тому подобное) могут создавать утечки, которых на самом деле нет в релизных сборках.

person rsalmeidafl    schedule 02.10.2018