2016-10-27 31 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