2016-10-27 6 views
0

Описаниепроблема производительности с помощью реакции-привязи внутри элемента в среагировать-виртуализированных список

У меня есть потенциально длинный список отрисовки элементов в реакции виртуализированных VirtualScroll.
Каждый элемент (строка) в списке имеет довольно большое количество элементов, один из которых открывает контекстное меню. Я пытаюсь использовать react-tether, чтобы отобразить это меню на HTML body (чтобы он не был скрыт, когда элемент находится в нижней части верхней части прокручиваемого списка) и сохраняйте меню «застрял» на моем элементе, пока пользователь прокручивает список.
Моя проблема заключается в том, что наблюдается заметное отставание в обновлении положения привязанного меню.

Некоторые из шагов, которые я взял до сих пор:

  1. Вынесено простой список, без VirtualScroll. Настроенное меню было сделано гладко, без заметного удара. Вот как я пришел к выводу, что проблема связана с
  2. Упрощенный мой rowRenderer до только триггера меню, как recommended here.
  3. Выполнено shouldComponentUpdate в компоненте строки. Это значительно улучшило воспринимаемую производительность, значительно уменьшило задержку, но это все еще заметно.
  4. Проверенная хронология Chrome devtools. Я вижу пересчеты, вызванные как Grid.js, так и tether.js.

Библиотека Версия:

  • реагирует виртуализированный V 7.24.3 (Большой проект, не готово сделать шаг к 8.x еще)
  • реагирует-привязанную V 0,5.. 0,2
  • реагируют v. 15.2.1

Рабочая Демонстрационный

https://plnkr.co/edit/f7OhCoCXkDsWbyjxhR3f

Скриншот:

screenshot

+0

«Проверка хронологии Chrome devtools». Я вижу переходы, вызванные как Grid.js, так и tether.js._ »- Не уверен в привязке, но в virtual-virtualized v8 я сделал две важные первоочередные оптимизации для обнаружения вверх -element-resize', что помешало ему сделать много ненужных переплавов. Если вы используете 'AutoSizer', это изменение может вам помочь. (Если вы этого не сделаете, это не будет актуальным.) Я был бы рад взглянуть на вашу проблему, если бы вы могли поделиться со мной кодом, даже если это всего лишь небольшой Plnkr. – brianvaughn

+0

@brianvaughn спасибо за быстрый ответ. 1. Я не использую 'AutoSizer', а наш собственный пользовательский обработчик изменения размера. Если это произойдет, я могу попытаться перейти на 8.x и переключиться на 'AutoSizer' 2. Я посмотрю, могу ли я создать общий вариант. Вероятно, хорошая идея в любом случае изолировать вопрос – burtyish

+0

@brianvaughn Я обновил свой вопрос ссылкой на рабочую демонстрацию на splunkr. Задержка видна. – burtyish

ответ

0

FYI, что Plnkr была нарушена. Он включал неправильную версию стилей (8.x вместо 7.x).

После устранения этого визуального «отставания», который я вижу, я не знаю, как исправить с версией 7.x. Проблема в том, что браузер управляет прокруткой в ​​другом потоке (так что JS не блокирует его и не вызывает отклика пользовательского интерфейса). Обычно это не заметно, потому что весь пользовательский интерфейс прокручивается вместе, однако в этом случае ваш модаль абсолютно позиционируется JS и поэтому иногда отстает от положения прокрутки браузера.

Это, как говорится, обновление до версии 8 дает альтернативу воротной подход, который делает исправить эту проблему, как показано в этом обновленном шлепнуть: https://plnkr.co/edit/NESPMzDz22JjwFVthve4?p=preview

Они ключ это:

render() { 
    const { menuOpen } = this.state; 
    const { index, style } = this.props; 

    // Make sure open cells are on a higher z-index than others 
    if (menuOpen) { 
    style.zIndex = 2; 
    } 

    return (
    <div 
     className="row" 
     style={style} 
    > 
     {list[index]} 

     {/* Render your button OR menu item here */} 
    </div> 
); 
} 
+0

Спасибо за предложение! Я мог бы использовать ваше предложение, если бы добавил дополнительную информацию о позиции моего элемента относительно краев его «прокрутки» и перевернул меню по вертикали, если он слишком близко к нижнему краю. – burtyish

+0

Моя первоначальная мотивация для подхода портала заключалась в том, чтобы предотвратить скрытие меню по краям списка (у которого есть 'overflow-y: hidden'), поэтому он может быть полностью видимым ниже даже последней строки. Я понимаю, что 'tether.js' оптимизирован для обновления местоположения элемента через JS _while scrolling_. – burtyish

+0

Я не знаю, каким образом можно достичь того, к чему вы стремитесь (исключая любой возможный источник задержки прокрутки) - при использовании технологии портала, например, tether.js. Лучшее, на что вы можете надеяться, - это максимально оптимизировать производительность, чтобы уменьшить отставание. С этой целью я рекомендую вам рассмотреть возможность обновления до виртуализованного v8, поскольку эта версия включает в себя более высокую оптимизацию производительности. Я понимаю вашу озабоченность по поводу переполнения границ родительского «списка». К сожалению, это ограничение подхода, о котором я говорил. Это может не соответствовать вашим потребностям. :/ – brianvaughn

 Смежные вопросы

  • Нет связанных вопросов^_^