10,000 rows
UIVirtualizedList mounts only the rows near the viewport, so ten thousand of them scroll as cheaply as ten. Data is imperative — build the array once and setData it; the list recycles row elements as you scroll, so render must depend only on the item it's given.
// UIVirtualizedList mounts only the rows near the viewport, so 10,000 items scroll as cheaply
// as ten. Data is driven imperatively — build the array once and setData it; the list recycles
// row elements as you scroll. render() must be pure over its item, so the row reads only `r`.
type Row = { id: number, name: string, weight: number }
const NAMES = ["Helium", "Carbon", "Neon", "Argon", "Iron", "Copper", "Zinc", "Krypton", "Xenon", "Radon"]
const rows: Row[] = Array.from({ length: 10000 }, (_, i) => ({
id: i,
name: `${NAMES[i % NAMES.length]} ${String(i + 1).padStart(4, "0")}`,
weight: Mathf.randomInt(1, 300),
}))
const list = UIVirtualizedList<Row>({
keyOf: r => String(r.id),
estimatedHeight: 64,
render: r => UIRow([
UIColumn([
UIText(r.name).style({ fontSize: 16, color: "white" }),
UIText(`#${r.id + 1}`).style({ fontSize: 12, color: "#5c6272" }),
]).style({ gap: 2 }),
UISpacer(),
UIText(`${r.weight} g`).style({ fontSize: 15, color: "#8b90a0", fontFamily: "monospaced" }),
]).style({ height: 64, px: 20, alignItems: "center", borderBottom: "1px solid #171b24" }),
}).style({ flexGrow: 1 })
list.setData(rows)
const screen = UIScreen([
UIColumn([
UIText("Elements").style({ fontSize: 28, fontWeight: 700, color: "white" }),
UIText(`${rows.length.toLocaleString("en-US")} rows, windowed`).style({ fontSize: 13, color: "#8b90a0" }),
]).style({ bgColor: "#0b0d12", px: 20, pt: "max(safe-top, 24px)", pb: 14, gap: 2 }),
list,
]).style({ bgColor: "#0b0d12" })
screen.open()
Press Run to launch the floating simulator. It stays open as you browse — opening another example just swaps the app inside it.