Skip to content

High-performance virtualized scrolling lists for react-lua.

License

Notifications You must be signed in to change notification settings

jsdotlua/virtualized-list-lua

Repository files navigation

VirtualizedList Lua

High-performance scrolling lists ported from React Native for react-lua.

license CI

A collection of virtual list components, supporting the most handy features:

  • Fully cross-platform
  • Optional horizontal mode
  • Configurable viewability callbacks
  • Header support
  • Footer support
  • Separator support
  • Pull to Refresh
  • Scroll loading
  • ScrollToIndex support
  • Multiple column support
  • Animation suppot

Virtualization massively improves memory consumption and performance of large lists by maintaining a finite render window of active items and replacing all items outside of the render window with appropriately sized blank space. The window adapts to scrolling behavior, and items are rendered incrementally with low-priority (after any running interaction responses) if they are far from the visible area, or with high-priority otherwise to minimize the potential of seeing blank space.

Caveats

Virtualized lists aren't appropriate for all situations. Here's some caveats:

  • Internal state is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or an external store like Rodux.
  • Everything is a PureComponent, which means that it will not re-render if props are shallow-equal. Make sure that everything your renderItem function depends on is passed as a prop (e.g. extraData) that is not shallow-equal after updates, otherwise your UI may not update on changes. This includes the data prop and parent component state.
  • In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate and momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application.
  • By default, the lists look for a key prop on each item and uses that for the React key. Alternatively, you can provide a custom keyExtractor prop.

Example

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")

local Packages = ReplicatedStorage.Packages

local React = require(Packages.React)
local ReactRoblox = require(Packages.ReactRoblox)
local VirtualizedList = require(Packages.VirtualizedList)

local View = VirtualizedList.View
local FlatList = VirtualizedList.FlatList

local e = React.createElement

local ITEM_COUNT = 10_000
local DATA = table.create(ITEM_COUNT)

for i = 1, ITEM_COUNT do
  DATA[i] = {
    id = HttpService:GenerateGUID(false),
    title = `Item {i}`,
  }
end

local function Item(props)
  return e(View, {}, {
    ItemText = e("TextLabel", {
      Size = UDim2.new(1, 0, 0, 40),
      Text = props.title,
    }),
  })
end

local function App()
  return e("ScreenGui", {
    ResetOnSpawn = false,
    ZIndexBehavior = Enum.ZIndexBehavior.Sibling,
  }, {
      Background = e("Frame", {
      AnchorPoint = Vector2.new(0.5, 0.5),
      Position = UDim2.fromScale(0.5, 0.5),
      Size = UDim2.fromScale(0.25, 0.4),
    }, {
      List = e(FlatList, {
        data = DATA,
        renderItem = function(entry)
          return e(Item, {
            title = entry.item.title,
          })
        end,
        keyExtractor = function(entry)
          return entry.id
        end,
      }),
    }),
  })
end

local root = ReactRoblox.createRoot(Instance.new("Folder"))
root:render(ReactRoblox.createPortal(e(App), Players.LocalPlayer.PlayerGui))

Documentation

These components are directly ported from React Native 0.68, so most documentation and articles should apply (modulo Lua syntax). More information on the provided list components can be found at:

TODO

  • Add unit tests from upstream React Native
  • Use darklua bundler to allow more files to easily run outside of Roblox
  • Add performance benchmarks

About

High-performance virtualized scrolling lists for react-lua.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages