react-virtualized 列表中项目内部 react-tether 的性能问题

Performance issue with react-tether inside item in a react-virtualized list

描述

我在反应虚拟化 VirtualScroll 中呈现了一个可能很长的项目列表。
列表中的每个项目(行)都有相当多的元素,其中一个元素会打开一个上下文菜单。我正在尝试使用 react-tether 在 HTML body 上呈现该菜单(这样当项目位于可滚动列表的 bottom/top 时它不会被隐藏)并且在用户滚动列表时将菜单 'stuck' 保留在我的项目中。
我的问题是更新联机菜单的位置有明显的滞后。

我目前采取的一些步骤:

  1. 呈现了一个简单的列表,没有 VirtualScroll。联机菜单呈现流畅,没有明显的卡顿。这就是我得出的结论,问题出在 react-virtualized
  2. 将我的 rowRenderer 简化为只有菜单触发器,如
  3. 在行组件中实现了 shouldComponentUpdate。这大大提高了感知性能,大大减少了延迟,但仍然很明显。
  4. 已检查 Chrome devtools 的时间表。我看到 Grid.jstether.js.
  5. 触发了回流

库版本:

工作演示

https://plnkr.co/edit/f7OhCoCXkDsWbyjxhR3f

截图:

仅供参考,Plnkr 已损坏。它包括错误的样式版本(8.x 而不是 7.x)。

修复后,我看到的视觉 "lag" 不是我知道如何用版本 7.x 修复的东西。问题是浏览器在不同的线程中管理滚动(这样 JS 就不会阻止它并导致 UI 感觉没有响应)。通常这不会引起注意,因为所有 UI 都一起滚动,但是在这种情况下 - 您的模态由 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>
  );
}