Значение объекта, возвращаемого, когда VirtualzedList медленно обновляется в React Native

Я работаю над созданием приложения для социальных сетей для своего университетского городка. Я использую React Native. Прямо сейчас я использую Redux для поддержания состояния моего приложения, React-redux для привязки состояния к различным компонентам React и redux-thunk для выполнения асинхронных вызовов API для извлечения и публикации данных. Любые данные, которые я получаю, я нормализую перед тем, как отправить их в хранилище Redux. Одна из серьезных проблем, с которыми я сталкиваюсь, заключается в том, что всякий раз, когда я начинаю прокручивать «Ленту» приложения, я получаю предупреждение:

VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. Object {
  "contentLength": 6298,
  "dt": 4840,
  "prevDt": 7619,
}

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

Примечание. Я использую FlatList для отображения отдельных сообщений в ленте.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
643
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Краткий обзор

  • dt — это время между двумя последними внутренними onScroll событиями, которое является косвенным измерением вашего времени рендеринга;
  • prevDt — то же измерение для одного цикла заранее;
  • contentLength — это основной размер (ширина или высота) отображаемого контента.

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


FlatList внутренности

FlatList React Native внутренне поддерживается VirtualizedList. Последний использует событие onScroll своего ScrollView для измерения показателей производительности.

Основные показатели, dt и prevDt, измеряют, как часто событие onScroll срабатывает для данного ScrollView. Оба измеряются путем сохранения текущей метки времени при возникновении события onScroll и сравнения ее с последним сохраненным значением. dt — текущая дельта, prevDt — дельта, измеренная в предыдущем пожаре.

В упрощенном виде это взаимодействие показано ниже, вы можете просмотреть полный код сюда.

onScroll(event) {
  const timestamp = event.timeStamp;
  const dt = timestamp - this.previousTimestamp;
  // ...
  this.previousTimestamp = timestamp;
}

Это измеряет, как часто сторона Javascript React Native получает событие от нативной стороны. Это косвенный, но очень эффективный способ измерить, потребовалось ли много времени для отображения вашего списка на нативной стороне.

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

onScroll(event) {
  // ...
  const contentLength = event.nativeEvent.contentSize.height;
  const visibleLength = event.nativeEvent.layoutMeasurement.height;
  // ...
}

Предупреждение

Описанное предупреждение выдается, когда выполняются все следующие условия (см. исходный код):

  • текущий рендер занял более 500 мс (это означает dt > 500);
  • предыдущий рендер также занимал более 500 мс (prevDt > 500);
  • а отображаемый контент более чем в пять раз больше фактического размера экрана (contentLength > 5 * visibleLength).

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

Как уменьшить эти проблемы, выходит за рамки этого ответа, но возникшая ошибка дает вам несколько хороших отправных точек (React.PureComponent, shouldComponentUpdate() и т. д.).

У меня есть еще одно сомнение. Почему иногда значение объекта сильно отличается, хотя я не изменил ни одного фрагмента кода?

Miraj Shah 01.03.2019 18:56

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

Etheryte 01.03.2019 19:00

Хорошо спасибо. Если вы не возражаете, я хотел бы задать еще одно сомнение. Последние два дня я работал над тем, чтобы избавиться от этого предупреждения. Я пытался использовать PureComponent и shouldComponentUpdate, но не добился большого успеха. Я хотел бы спросить, имеет ли значение то, как я передаю реквизиты дочерним компонентам. Один из способов — передать реквизит вместе с data из FlatList. Другой просто передает post_id в качестве реквизита дочерним компонентам, а затем использует соединение для привязки каждого дочернего элемента к хранилищу для получения информации, такой как заголовок сообщения, лайки и т. д.

Miraj Shah 01.03.2019 19:12

@MirajShah Здесь следует иметь в виду, что значения предупреждений представляют собой предустановленные статические значения, которые служат только в качестве ориентира. Например, если вы используете эмулятор с малым объемом памяти, маловероятно, что вы когда-нибудь сможете выполнить предлагаемые значения. Обязательно протестируйте свое приложение на реальном устройстве, чтобы понять, как оно работает. Что касается вашего вопроса о реквизитах, он немного великоват для комментария, но вскоре я передам идентификатор сообщения детям и позволю им обработать его.

Etheryte 01.03.2019 19:33

Другие вопросы по теме