Редактировать 20 декабря 2019: информация об этом ответе стала частью официальные документы. Вам стоит это увидеть!
Изменить от 26 мая 2018 г.: этот ответ стал более крупным и полным постом на гитхаб
Если вы следите за этой веткой, вы увидите, что команда реагирования уже знает о эта проблема с производительностью.
В этом вопросе нет серебряной пули, вы должны учитывать компромиссы каждого подхода и то, что, по вашему мнению, является хорошим опытом для вашей аудитории. Но, к счастью, есть несколько настроек, которые вы можете попробовать и улучшить свой FlatList
.
Термины и значения
Используется много терминов (в документах или некоторых проблемах ), что сначала меня смутило. Итак, давайте уберем это с самого начала.
VirtualizedList — это компонент, лежащий в основе FlatList
, и реализация React Native 'виртуальный список".
Производительность в этом контексте подразумевает плавную (не прерывистую) прокрутку (и навигацию по списку и обратно).
Потребление памяти в данном контексте – это объем информации о вашем списке, который хранится в памяти, что может привести к сбою приложения.
Пустые области означают, что VirtualizedList не смог отобразить ваши элементы достаточно быстро, поэтому вы вводите часть своего списка с неотображенными компонентами.
Окно здесь не область просмотра, а размер области, в которой должны отображаться элементы.
Реквизит
Один из способов улучшить ваш FlatList
— настроить его реквизит. Вот список реквизита, который может помочь вам в этом.
removeClippedSubviews
Вы можете установить свойство removeClippedSubviews
в значение true, которое размонтирует компоненты, находящиеся за пределами окна.
Win: это очень удобно для памяти, так как у вас всегда будет небольшой отображаемый список.
Компромиссы. Имейте в виду, что в этой реализации могут быть ошибки, например отсутствующий контент, если вы используете его для компонента, который не будет размонтирован (например, маршрут навигации). Он также может быть менее производительным, имея прерывистую анимацию прокрутки для больших списков со сложными элементами на не очень хороших устройствах, поскольку он выполняет сумасшедшее количество вычислений за прокрутку.
максторендерпербатч
Вы можете установить maxToRenderPerBatch={number}
, который является реквизитом VirtualizedList
, который можно передать непосредственно в FlatList
. При этом вы можете контролировать количество элементов, отображаемых в пакете, то есть следующий фрагмент элементов, отображаемых при каждом прокрутке.
Победа. Установка большего числа означает меньше видимых пустых областей при прокрутке (лучше скорость заполнения).
Компромисс: большее количество элементов в пакете означает меньшую производительность JavaScript, что означает меньшую скорость отклика (нажатие элемента и открытие сведений). Если у вас есть статический и неинтерактивный список, это может быть выходом.
InitialNumToRender
Вы можете установить initialNumToRender={number}
. Это означает начальное количество элементов для рендеринга.
Победа. Вы можете установить это значение на точное количество элементов, которые будут покрывать экран для каждого устройства. Это может значительно повысить производительность при рендеринге компонента списка.
Компромисс: вы, скорее всего, увидите пустые области при установке низкого initialNumToRender
.
размер окна
Вы можете установить windowSize={number}
. Передаваемое здесь число является единицей измерения, где 1 эквивалентно высоте вашего окна просмотра. Значение по умолчанию — 21, то есть 10 окон просмотра вверху, 10 внизу и один между ними.
Победа. Если вы в основном беспокоитесь о производительности, вы можете установить большее значение windowSize
, чтобы ваш список работал плавно и с меньшим количеством пробелов. Если вы в основном беспокоитесь о потреблении памяти, вы можете установить более низкое значение windowSize
, чтобы ваш отображаемый список был меньше.
Компромисс: чем больше windowSize
, тем больше потребление памяти. Для более низкого windowSize
у вас будет более низкая производительность и большее изменение видимости пустых областей.
НаследиеРеализация
Это свойство, когда оно равно true, заставит ваш FlatList
полагаться на более старый ListView
вместо VirtualizedList
.
Победа. Это определенно повысит производительность вашего списка, поскольку он удаляет виртуализацию и отображает все ваши элементы одновременно.
Компромисс. Потребление памяти резко возрастает, и велика вероятность, что большой список (более 100 элементов) со сложными элементами приведет к сбою вашего приложения. Он также выдает предупреждение о том, что вышеуказанные настройки не будут работать, потому что вы теперь находитесь в ListView.
отключить виртуализацию
Вы увидите, как люди выступают за использование этой опоры по некоторым вопросам. Но теперь это устарело. Раньше это делало что-то похожее на legacyImplementation
.
Элементы списка
Есть также несколько беспроигрышных стратегий, которые включают компоненты вашего списка. Они часто управляются VirtualizedList, поэтому они должны быть быстрыми.
Используйте простые компоненты
Чем сложнее ваши компоненты, тем медленнее они будут отображаться. Старайтесь избегать большого количества логики и вложенности в элементы списка. Если вы часто повторно используете этот компонент элемента списка в своем приложении, создайте дубликат только для ваших больших списков и сделайте их как можно менее логичными и менее вложенными.
Используйте легкие компоненты
Чем тяжелее ваши компоненты, тем медленнее они рендерятся. Избегайте тяжелых изображений (используйте обрезанную версию для элементов списка, как можно меньше). Поговорите со своей командой дизайнеров, используйте в своем списке как можно меньше эффектов, взаимодействий и информации. Сохраните их в деталях вашего товара.
Использовать следуетобновление компонента
Реализуйте проверку обновлений для своих компонентов. PureComponent в React в основном нужен, когда у вас нет времени на размышления. Если вы читаете это, значит, у вас есть время, поэтому создайте самые строгие правила для компонентов вашего списка. Если ваш список достаточно прост, вы можете даже использовать
shouldComponentUpdate() {
return false
}
person
Filipe Merker
schedule
25.05.2018