2016-10-27 33 views
0

说明性能问题,在一个反应​​虚拟化列表

反应系绳内的项目我有一个潜在的长期的反应虚拟化VirtualScroll呈现的产品清单。
列表中的每个项目(行)都有相当多的元素,其中一个打开上下文菜单。我正在尝试使用react-tether在HTML body上呈现该菜单(当项目位于可滚动列表的底部/顶部时,它不会隐藏),并在用户滚动时让菜单“卡住”列表。
我的问题是,更新系绳菜单的位置有明显的滞后。

一些我到目前为止所采取的步骤:

  1. 渲染一个简单的列表,无需VirtualScroll。系绳菜单顺利进行,没有明显的麻烦。这就是我如何得出结论,问题是react-virtualized
  2. 简化我的rowRenderer下降到只有菜单触发器,为recommended here
  3. 在行组件中实现了shouldComponentUpdate。这极大地提高了感知性能,大大减少了延迟,但仍然引人注目。
  4. 检查Chrome devtools的时间表。我看到由Grid.jstether.js触发的回流。

库版本:

  • 反应虚拟化v 7.24.3(大项目,没有准备好让一步又8.X)
  • 反应系绳v 0.5。 0.2
  • 反应诉15.2.1

工作演示

https://plnkr.co/edit/f7OhCoCXkDsWbyjxhR3f

截图:

screenshot

+0

“_Checked Chrome devtools'时间轴,我看到由Grid.js和tether.js._触发的回流” - 不确定系绳,但在反应 - 虚拟化v8中,我对上游检测进行了2次重要的perf优化-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不会阻止它并导致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> 
); 
} 
+0

感谢您的建议!如果我添加了能够计算出我的元素相对于它的“滚动父级”边缘的位置的功能,并且如果它太靠近底部边缘则垂直翻转菜单,我可以使用您的建议。 – burtyish

+0

我最初采取入口方法的动机是为了防止菜单被列表边缘(它具有'overflow-y:hidden')隐藏,所以它甚至可以在最后一行之下完全可见。这是我的理解,'tether.js'被优化,以通过JS _同时滚动_更新元素的位置。 – burtyish

+0

我不知道有什么方法可以实现您的目标 - (消除任何可能的滚动滞后来源) - 同时使用像tether.js使用的门户技术。你可以期望的最好的方式就是尽可能地优化性能以减少延迟。为此,我鼓励您考虑升级到react-virtualized v8,因为该版本包含更多性能优化。 我明白你关心溢出父'List'的边缘。不幸的是,这是我提到的方法的局限性。它可能不适合你的需求。 :/ – brianvaughn