Virtualization vs Recycling
Давайте разберемся, какие бывают подходы к оптимизации списков на React Native.
Начнем с базы. ScrollView рендерит все child-элементы сразу.
Как только ваш список станет длиннее экрана, это может стать проблемой.
Для решения этой проблемы React Native предоставляет VirtualizedList и реализованные на его базе FlatList и SectionList.
Вместо того чтобы рендерить все элементы списка, мы как бы создаем окно, которое "идет" вместе со скроллом по списку и рендерит только то, что попадает в это окно.
Настраивать параметры виртуализации можно следующими свойствами:
windowSize — число, задающее размер вашего окна. Значение по умолчанию — 21, что означает, что окно равно 10 экранам сверху, 10 экранам снизу и одному текущему. Уменьшение этого числа позволит сократить количество элементов, которые будут рендериться одновременно.
maxToRenderPerBatch — параметр, задающий количество элементов, которые будут рендериться за раз во время события скролла. Значение по умолчанию — 10.
Итак, давайте представим, что у вас есть список из 100 элементов, и на экран умещается 10 из них.
При открытии этого списка с дефолтными настройками FlatList произойдет рендеринг 10 экранов вниз (то есть всего вашего списка).
Единственное отличие от ScrollView будет в том, что рендеринг этот будет происходить не сразу, а батчами по 10 элементов, что сделает UI более отзывчивым.
Как же нам оптимизировать список так, чтобы не рендерить лишние элементы и при этом избежать проблем с быстрой прокруткой?
Ответ — использовать ♻️ Recycling.
Это техника, при которой мы переиспользуем существующие компоненты вместо того, чтобы создавать и удалять их заново.
В примере выше, если мы уменьшим размер окна, каждый раз, когда элемент будет выходить за пределы окна, он будет утилизироваться.
А что если вместо этого мы создадим окно размером в 2 экрана? И вместо того чтобы каждый раз пересоздавать компоненты с новыми свойствами, будем менять свойства существующих компонентов в соответствии с текущими элементами в окне.
Именно этот принцип реализует RecyclerListView и построенный на его базе FlashList, который предоставляет API, максимально похожий на FlatList.
Используя FlashList, вы значительно сократите потребление памяти и увеличите производительность списков. Однако стоит помнить о следующих принципах:
1️⃣ Старайтесь избегать использования useState внутри элементов списка или продумайте логику его сброса (например, через useRef).
2️⃣Если ваш список состоит из нескольких типов компонентов, реализуйте метод getItemType.
3️⃣Посчитайте примерный размер элемента списка для параметра estimatedItemSize — это позволит лучше определить размер окна для списка.
4️⃣Если вам нужен аналог SectionList, посмотрите пример реализации через getItemType.
Если придерживаться этих правил, практически во всех случаях замена FlatList на FlashList принесет значительное увеличение производительности ваших списков.
React Native World | Навигация по каналу
Post #14
517
- 🔥 13
- 👍 6
- ❤ 2