在 React 裡優雅地使用 Virtual List!

Avatar

David / 2022-07-12



在 React 裡優雅地使用 Virtual List!

前言

使用 Virtual List 的原因在 React 的官方文檔裡有提到。當你的應用程式在渲染大數目的 long list 時,如果沒有處理好,會讓瀏覽器卡頓在那個畫面,有點像是當機的狀態。

這是因為瀏覽器在畫畫面的時候不會只把你的可視區域畫出來,他會把資料全部都畫完後才繼續做其他的事,但使用者也不一定會一一地把資料全部看完,這就造成效能上的浪費。所以我們需要用一個 windowing 的技術。

window

簡單來說,這個技術的核心就是讓瀏覽器只製作使用者可視區域內的畫面,當使用者離開那個範圍時就把製作好的東西拿掉,藉此提升效能。

更詳細的介紹可以看這篇文章

react-virtualized

其實我一開始學習這個技術的時候也是使用 react-virtualized,畢竟是能找到最大的 library ,但其實我個人覺得沒有非常好用,我需要一層一層的把我的 List 包起來,還要另外寫一個 render,造成開發及維護上的一點點困難。

像這樣:

const AllRows = ({ index, key, style }) => {
  return (
    <MyComponent key=key />
  )
}

<WindowScroller>
{({ height, scrollTop }) => (
    <AutoSizer disableHeight>
      {({ width }) => (
          <List
              autoHeight={true}
              height={height}
              width={width}
              scrollTop={scrollTop}
              rowHeight={height / 2.75}
              rowRenderer={AllRows}
              rowCount={length}
              overscanRowCount={10}
          />
      )}
    </AutoSizer>
)}
</WindowScroller>

雖然能達成目的,但用起來還是有點不順手就是了。

直到我遇見了 react-virtuoso。

React-virtuoso

剛剛上面那一長串 瞭解了一下 React-virtuoso 後,只花了不到五分鐘就做出一樣的效果

像這樣:

<Virtuoso
  style={{
    height: '100%'
  }}
  useWindowScroll
  overscan={100}
  endReached={fetchMoreRow}
  data={articles}
  itemContent={(index, article) => {
    return (
      <MyComponent key=key />
    )
  }}
/>

超簡單的 code 就可以達成一樣的事情,真的是謝謝作者大大的減少了負擔!

資料來源

  1. react-virtuoso github
  2. Windowing 中文解釋
  3. 官方說明